代码之家  ›  专栏  ›  技术社区  ›  Deepesh Meena

使用tcp将文件从服务器发送到客户端

  •  0
  • Deepesh Meena  · 技术社区  · 6 年前

    我试图将文件从服务器发送到客户端,代码运行时没有任何错误,但当客户端创建文件时,我没有获得服务器发送的文件中所需的数据。

    我在StackOverflow本身上寻找了一些解决方案,但无法解决我的问题,因为我对socket编程还不熟悉。有人能告诉我哪里出了问题吗。请帮帮我!!

    这是代码

    服务器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;
    }
    

    客户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 回复  |  直到 6 年前
        1
  •  1
  •   cninicu    6 年前

    检查此项:

    服务器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);
        }       
    }       
    

    客户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);
    }
    
        2
  •  0
  •   Deepesh Meena    6 年前

    所以,以前我试图解决它时,我遇到了一些问题,但现在我成功地解决了它 客户端代码:

    #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;
    }
    

    根据需要进行更改。