使用tcp

时间:2018-04-14 20:28:53

标签: sockets tcp tcpclient

我正在尝试从服务器向客户端发送文件并且代码正在运行而没有任何错误,但是当客户端创建文件时,我没有获得服务器正在发送的文件中所需的数据。 / p>

我在StackOverflow本身上查找了一些解决方案,但无法解决我的问题,因为我是socket编程的新手,有人可以告诉我哪里出错了。请帮助我!!

这是代码

server.c

// Server side C/C++ program to demonstrate Socket programming
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h> 

#include <netdb.h>
#include <sys/sendfile.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h>

//#define PORT 8080
int main(int argc, char const *argv[])
{
int fq;

 struct sockaddr_in client,server;
    struct hostent *h;

struct stat st;
int len = 0;
int PORT = strtol(argv[1], NULL, 10);


 char *filename = strdup(argv[2]);




    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char *hello = "Hello from server";

if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}


    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // Forcefully attaching socket to the port 8080
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                                                  &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );

    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr *)&address, 
                                 sizeof(address))<0)
    {
        fprintf(stderr, "%s", "Bind Failed\n");    
            exit(2);
    }
    else {   printf("BindDone: %s\n ", argv[1]);

}


    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }

else {   printf("ListenDone: %s\n ", argv[1]);

}

    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, 
                       (socklen_t*)&addrlen))<0)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }
///////////////////////////////////////////
    fq = open(filename, O_RDONLY);
    if( fq < 0 )
    {
        fprintf(stderr, "%s", "File error\n");    
            exit(3);
    }

stat(filename,&st);
    len = st.st_size;

    if(sendfile(server_fd,fq,0,len) < 0)
    {
        perror("send error");
        exit(1);
    }

 //   close(sd);





    valread = read( new_socket , buffer, 1024);
    printf("%s\n",buffer );
    send(new_socket , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");

    printf("TransferDone: %s\n ", "bytes\n");

 close(fq);
close(server_fd);
 return 0;
}

client.c

// Client side C/C++ program to demonstrate Socket programming

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#define PORT 8080
#define MAX_LEN 512

int main(int argc, char const *argv[])
{
struct sockaddr_in server;
    struct sockaddr_in client;  


int rn ;
    struct sockaddr_in address;
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    char *hello = "Hello from client";
    char buffer[MAX_LEN] ;

    FILE *fp;
    int i;
    char *filename = strdup(argv[2]);




if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}



    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Socket creation error \n");
        return -1;
    }

    memset(&serv_addr, '0', sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // Convert IPv4 and IPv6 addresses from text to binary form
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) 
    {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        fprintf(stderr, "%s", "Server connection error\n");    
            exit(2);
    }

///////////////////////
fp=fopen( filename, "ab");
    if(fp == NULL)
    {
        fprintf(stderr, "%s", "file not readable\n");    
            exit(3);
    }

////////////////////////

while(1)
    {
        rn=recv(sock,buffer,MAX_LEN,0);

        if(rn < 0)
        {
            printf( "Can 't receive file!\n ");
            exit(1);
        }

        buffer[rn]= '\0 ';

        if(rn != 0)
        {
            fwrite(buffer,1,512,fp);
            bzero(buffer,sizeof(buffer));
        }
        else
        {
            printf("receive over.\n");
            break;
        }
    }



/////////////////////////



    send(sock , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    valread = read( sock , buffer, 1024);
    printf("%s\n",buffer );

fclose(fp);
    return 0;
}

2 个答案:

答案 0 :(得分:0)

检查一下:

server.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define PORT 2024
extern int errno;
int main (){
  struct sockaddr_in server;
  struct sockaddr_in from;  
  int sd;
  sd = socket (AF_INET, SOCK_STREAM, 0);
  bzero (&server, sizeof (server));
  bzero (&from, sizeof (from));

  server.sin_family = AF_INET;  
  server.sin_addr.s_addr = htonl (INADDR_ANY);
  server.sin_port = htons (PORT);
  if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1){
      perror ("bind(). error\n");
      return errno;
  }
  if (listen (sd, 5) == -1){
      perror ("listen(). error\n");
      return errno;
  }
  while (1){
      int client;
      int length = sizeof (from);
      printf ("connect to port :  %d...\n",PORT);
      fflush (stdout);
      client = accept (sd, (struct sockaddr *) &from, &length);
      if (client < 0)
         continue;
      char file[100];

      read (client, file, 100) <= 0;
      printf("Filename : %s\n\n", file); 
      //
        FILE *fl = fopen(file, "r");
        char text[500]; //your file size
        int len = 0;
        char c;

        while((c = fgetc(fl)) != EOF){
            text[len] = c;
            len++;    
        }
        text[len] = '\0';
        //printf("%d", len);
        //printf("%s", text);
        write(client, &len, 4);
        write(client, text, len);
      close (client);
    }       
}       

client.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
extern int errno;
int port;
int main (int argc, char *argv[]){
  int sd;   
  struct sockaddr_in server;

  if (argc != 3){
      printf ("%s <server_adress> <port>\n", argv[0]);
      return -1;
  }
  port = atoi (argv[2]);
  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1){
      perror ("socket() error.\n");
      return errno;
  }
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = inet_addr(argv[1]);
  server.sin_port = htons (port);
  if (connect (sd, (struct sockaddr *) &server,sizeof (struct sockaddr)) == -1){
      perror ("connect(). error\n");
      return errno;
  }
  char file[100]; 
  printf("Give me filename: ");
  fflush(stdout);
  scanf("%s", file);
  if (write (sd, file, 100) <= 0)
    {
      perror ("[client]Eroare la write() spre server.\n");
      return errno;
    }
   int len;
   char text[500];
   read(sd, &len, 4);
   read(sd, text, len);
   //printf("%s\n", text);
   FILE *fl = fopen("newFile.txt", "w");
   fprintf(fl, "%s", text);
   fclose(fl);
   close (sd);
}

此处客户端向服务器提供文件名,它(服务器)打开文件并从中读取所有内容,将数据发送给创建新文件的客户端并将数据写入新创建的文件。

UPD。

concurentServer.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#define PORT 2908
extern int errno;
typedef struct thData{
    int idThread; 
    int cl;
}thData;
static void *treat(void *); 
void answer(void *);

int main (){
  struct sockaddr_in server;
  struct sockaddr_in from;  
  int nr;    
  int sd;   
  int pid;
  pthread_t th[100];  
    int i=0;
  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1){
      perror ("[server]socket().\n");
      return errno;
  }
  int on=1;
  setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
  bzero (&server, sizeof (server));
  bzero (&from, sizeof (from));
    server.sin_family = AF_INET;    
    server.sin_addr.s_addr = htonl (INADDR_ANY);
    server.sin_port = htons (PORT);
  if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1) {
      perror ("[server]bind().\n");
      return errno;
  }
  if (listen (sd, 2) == -1){
      perror ("[server]listen().\n");
      return errno;
  }
  while (1){
      int client;
      thData * td;      
      int length = sizeof (from);
      printf ("[server]Port :  %d...\n",PORT);
      fflush (stdout);
      if ( (client = accept (sd, (struct sockaddr *) &from, &length)) < 0){
             perror ("[server]accept().\n");
             continue;
        }

       int idThread; 
       int cl; 
    td=(struct thData*)malloc(sizeof(struct thData));   
    td->idThread=i++;
    td->cl=client;
      pthread_create(&th[i], NULL, &treat, td);             
    }
};


static void *treat(void * arg)
{       
        struct thData tdL; 
        tdL= *((struct thData*)arg);    
        printf ("[thread]- %d - Waiting for message...\n", tdL.idThread);
        fflush (stdout);         
        pthread_detach(pthread_self());     
        answer((struct thData*)arg);
        close ((intptr_t)arg);
        return(NULL);   

};


void answer(void *arg){
        char file[100];
          int ap;
        struct thData tdL; 
          tdL= *((struct thData*)arg);
        //
        if (read (tdL.cl, file, 100) <= 0){
                  printf("[Thread number : %d]\n",tdL.idThread);
              }
          FILE *fl = fopen(file, "r");
        char text[500]; //your file size
        int len = 0;
        char c;

        while((c = fgetc(fl)) != EOF){
            text[len] = c;
            len++;    
        }
        text[len] = '\0';
        //printf("%d", len);
        //printf("%s", text);
        write(tdL.cl, &len, 4);
        write(tdL.cl, text, len);
}

答案 1 :(得分:0)

所以当我以前尝试解决它时,我遇到了问题,但是现在我已经成功解决了 客户端代码:

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>

int main(int argc, char const *argv[])
{

int byte_count=0;
int sockfd = 0;
    int bytesReceived = 0;
    char recvBuff[256];
    memset(recvBuff, '0', sizeof(recvBuff));
    struct sockaddr_in serv_addr;

if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}

char *first_argument = strdup(argv[1]);
//printf("%s\n",first_argument);
char *filename = strdup(argv[2]);

//extract port and ip address from first argument


int c;
//char *first_argument = strdup(argv[1]);

for(int i = 0; first_argument[i] != '\0'; i++) {

if(first_argument[i]==':') c=i;

}


char *ip = (char*) malloc(c+1);
char *tto = (char*) malloc(c+1);
strncpy(ip, first_argument, c);
strncpy(tto, first_argument+c+1, c);


//printf("%s\n",ip);
//printf("%s\n",tto);

int port = atoi(tto);

//printf("%d\n",port);


////////////////////////////////
    /* Create a socket first */
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    }

    /* Initialize sockaddr_in data structure */
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port); // port
    serv_addr.sin_addr.s_addr = inet_addr(ip);

    /* Attempt a connection */
connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
printf("ConnectDone: %s\n", argv[1]);   

//    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)
  //  {
    //     fprintf(stderr, "%s", "server connect failed\n");    
    //      exit(1);

    //}

    /* Create file where data will be stored */
    FILE *fp;
    fp = fopen(filename, "ab"); 
    if(NULL == fp)
    {
        fprintf(stderr, "%s", "error opening file\n");    
            exit(3);
    }

    /* Receive data in chunks of 256 bytes */
    while((bytesReceived = read(sockfd, recvBuff, 256)) > 0)
    {
   //     printf("Bytes received %d\n",bytesReceived);    
        // recvBuff[n] = 0;
        fwrite(recvBuff, 1,bytesReceived,fp);
        // printf("%s \n", recvBuff);
byte_count +=bytesReceived;
    }

  //  if(bytesReceived < 0)
    //{
      //  printf("\n Read Error \n");
    //}

printf("FileWritten: %d bytes\n", byte_count);   
    return 0;
}

和服务器代码:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>

int main(int argc, char const *argv[])
{

    int byte_count = 0 ;
    int listenfd = 0;
    int connfd = 0;
    struct sockaddr_in serv_addr;
    char sendBuff[1025];
    int numrv;

//checking if correct number of arguments are given on the command line
if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}
//converting arguments to their correct types to use them e.g. port num and filename 
int PORT = strtol(argv[1], NULL, 10);
char *filename = strdup(argv[2]);
//printf("%s",filename);


    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    //printf("Socket retrieve success\n");

    memset(&serv_addr, '0', sizeof(serv_addr));
    memset(sendBuff, '0', sizeof(sendBuff));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(PORT);


//bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
//checking if bind fails??



if (bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr))== -1)
    {
        fprintf(stderr, "%s", "Bind Failed\n");    
            exit(2);
    }
else       printf("BindDone: %s\n", argv[1]);

//}




    if(listen(listenfd, 10) == -1)
    {
        printf("Failed to listen\n");
        return -1;
    }
else {   printf("ListenDone: %s\n", argv[1]);

}

   //while(1)
    //{
        connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL);

        /* Open the file that we wish to transfer */
        FILE *fp = fopen(filename,"rb");
        if(fp==NULL)
        {

//checking if there is some problem with file or file present or not??

             fprintf(stderr, "%s", "File open error\n");    
            exit(3); 
        }   

        /* Read data from file and send it */
        while(1)
        {
            /* First read file in chunks of 256 bytes */
            unsigned char buff[256]={0};
            int nread = fread(buff,1,256,fp);
        byte_count +=nread;

          //  printf("Bytes read %d \n", nread);        

            /* If read was success, send data. */
            if(nread > 0)
            {
               // printf("Sending \n");
                write(connfd, buff, nread);
            }


            if (nread < 256)
            {
printf("TransferDone: %d bytes\n" ,byte_count);
                if (feof(fp)){

                    //printf("End of file\n");
}

if (ferror(fp))
                    printf("Error reading\n");
                break;
            }


        }

        close(connfd);
        sleep(1);
    //}


    return 0;
}

根据您的需要进行更改。