title: How to send multiple files through a socket in c?
body: <p>I am writing a c program to transfer multiple files from a client to a server. The client is sending 20 bytes at a time. When it reaches the end of the file, I am sending a flag (just a string saying "done") to the server, so it will know when the first file ends. But the problem is when the client is sending the last few remaining bytes of the file which might not be 20 bytes, the server on the other side would be trying to receive 20 bytes.<br>
  So what happens is that the last remaining bytes (assume 15 bytes for understanding the problem) of the file is sent in one send(). And after the file has ended, another send() to send the flag (which is of size 5bytes) will be read by one recv(). Because of this, the flag will never be recognized at the server and as the client starts to send the second file, the server will continue on to append the second file contents to the first one.  </p>
  
  <p>What can be done so that I can transfer multiple files without mixing them up (i.e distinguish between different files )?<br>
  <em>(Also I don't want to share the file size with the server before sending the file)</em>    </p>
  
  <p>I appreciate any suggestions!</p>
  
  <p><strong>Client code:</strong> </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;string.h&gt;
  #include &lt;signal.h&gt;
  #define PORT 8080
  #define BUFSIZE 20
  
  int main(int argc, char const *argv[])
  {
      struct sockaddr_in address;
      int sock = 0, valread;
      struct sockaddr_in serv_addr;
      char status[15]={0};
      char buffer[BUFSIZE]={0};
      int read_size=0,i=1,sent_size=0;    
  
      FILE *f1,*f2;    
      f1=fopen("M1.txt","r");
      f2=fopen("M2.txt","r");
      if(f1==NULL)
      {
          printf("Unable open file\n");
          exit(0);
      }
      if(f2==NULL)
      {
          printf("Unable open file\n");
          exit(0);
      }
      if ((sock = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
      {
          printf("\n Socket creation error \n");
          return -1;
      }
      memset(&amp;serv_addr, '0', sizeof(serv_addr));
  
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_port = htons(PORT);
  
      if(inet_pton(AF_INET, "127.0.0.1", &amp;serv_addr.sin_addr)&lt;=0) 
      {
          printf("\nInvalid address/ Address not supported \n");
          return -1;
      }
  
      if (connect(sock, (struct sockaddr *)&amp;serv_addr, sizeof(serv_addr)) &lt; 0)
      {
          printf("\nConnection Failed \n");
          return -1;
      }
  
      while((read_size=fread(buffer,1,BUFSIZE,f1))&gt;0)
      {
          sent_size=send(sock,buffer,read_size , 0 );
          fprintf(stderr,"%d th sent_size  %d\n",i,sent_size); //Just printing how many bytes have been sent in every iteration.
          if(read_size!=BUFSIZE)
          {
              fprintf(stderr,"%dth read... read_size is not 20 and it is %d\n",i,read_size ); //printing the last few remaining bytes when the last read from the file might not have exact 20 bytes
          }
          i++;
      }
  
      strcpy(status,"done");                      //Flag to be sent to the server to indicate that the file transfer has been completed
      send(sock,status,strlen(status)+1, 0 );
      printf("First file sent\n");
  
  
      for(i=0;i&lt;BUFSIZE;i++)
          buffer[i]='\0';
      i=1;
      while((read_size=fread(buffer,1,BUFSIZE,f2))&gt;0)
      {
          sent_size=send(sock,buffer,read_size , 0 );
          fprintf(stderr,"%d th sent_size  %d\n",i,sent_size); //Just printing how many bytes been sent in every iteration.
          if(read_size!=20)
          {
              fprintf(stderr,"%d th read...read_size is not 20 and it is %d\n",i,read_size );//printing the last few remaining bytes when the last read from the file might not have exact 20bytes
          }
          i++;
      } 
      send(sock,status,strlen(status)+1, 0 );
      printf("Second file sent\n");
      fclose(f1);
      fclose(f2);
      close(sock);
      return 0;
  }
  </code></pre>
  
  <p><strong>Server code :</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;string.h&gt;
  #define PORT 8080
  #define BUFSIZE 20
  
  int main(int argc, char const *argv[])
  {
      int server_fd, new_socket;
      struct sockaddr_in address;
      int opt = 1;
      int addrlen = sizeof(address);
      char status[15]={0},buffer[BUFSIZE]={0}; 
      int read_size=0,i=1,j;
  
      FILE *f1,*f2;
      f1=fopen("R1.txt","w+");
      f2=fopen("R2.txt","w+");
  
      if(f1==NULL)
      {
          printf("Unable open file\n");
          exit(0);
      }
      if(f2==NULL)
      {
          printf("Unable open file\n");
          exit(0);
      }
  
      if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
      {
          perror("socket failed");
          exit(EXIT_FAILURE);
      }
      if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &amp;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 );
  
      if (bind(server_fd, (struct sockaddr *)&amp;address,sizeof(address))&lt;0)                                 
      {
          perror("bind failed");
          exit(EXIT_FAILURE);
      }
      if (listen(server_fd, 3) &lt; 0)
      {
          perror("listen");
          exit(EXIT_FAILURE);
      }
      printf("Server Waiting\n");
      if ((new_socket = accept(server_fd, (struct sockaddr *)&amp;address, 
                         (socklen_t*)&amp;addrlen))&lt;0)
      {
          perror("accept");
          exit(EXIT_FAILURE);
      }
  
      while((read_size=recv(new_socket,buffer,BUFSIZE,0))&gt;0)
      {
          printf("%d th Read size %d \n",i,read_size );
          if(read_size!=BUFSIZE)
              {
                  printf("%d th read... read size is:%d, Data read : ",i,read_size ); 
                  for(j=0;j&lt;read_size;j++) //Printing the contents of the buffer when read size is less than 20 ()
                  printf("%c",buffer[j]);    
                  printf("\n");
  
                  if(strcmp(buffer,"done")==0) 
                  {
                      printf("Flag received : done\n");
                      break;
                  }
              }
          fwrite( buffer,sizeof(char),read_size,f1);
          i++;
      }
  
      printf("\nFirst File received\n");
  
      for(i=0;i&lt;BUFSIZE;i++)
      buffer[i]='\0';
  
      i=1;
  
      while((read_size=recv(new_socket,buffer,BUFSIZE,0))&gt;0)
      {
          printf("%d th Read size %d \n",i,read_size );
          if(read_size!=BUFSIZE)
              {
                  printf("%d th read... read size is:%d, Data read : ",i,read_size ); 
                  for(j=0;j&lt;read_size;j++) //Printing the contents of the buffer when read size is less than 20 
                  printf("%c",buffer[j]);    
                  printf("\n");
  
                  if(strcmp(buffer,"done")==0) 
                  {
                      printf("Flag received : done");
                      break;
                  }
              }
          fwrite( buffer,sizeof(char),read_size,f2);
          i++;
      }
  
      printf("\nSecond File received\n"); 
  
      fclose(f1);
      fclose(f2);
      close(new_socket);
      return 0;
  }
  </code></pre>
  
  <p><strong>Server Output:</strong></p>
  
  <blockquote>
    <p>Server Waiting <br/>1 th Read size 20<br/>  2 th Read size 20<br/>  3 th Read size 20<br/>
    4 th Read size 20<br/>  5 th Read size 20<br/>  6 th Read size 20<br/>  7 th Read
    size 20<br/>  8 th Read size 20<br/>  9 th Read size 20<br/>  10 th Read size 20<br/>  11
    th Read size 20<br/>  12 th Read size 8<br/>  12 th read... read size is:8, Data
    read : e port.
    <br/>
    13 th Read size 5<br/>  13 th read... read size is:5, Data read : done<br/> Flag
    received : done<br/></p>
    
    <p>First File received</p>
    
    <p>Second File received</p>
  </blockquote>
  
  <p><strong>Client Output:</strong></p>
  
  <blockquote>
    <p>1 th sent_size  20<br/> 2 th sent_size  20<br/> 3 th sent_size  20<br/> 4 th
    sent_size  20<br/> 5 th sent_size  20<br/> 6 th sent_size  15<br/> 6th read...
    read_size is not 20 and it is 15<br/> First file sent<br/> 1 th sent_size  20<br/> 2
    th sent_size  20<br/> 3 th sent_size  20<br/> 4 th sent_size  20<br/> 5 th sent_size 
    20<br/> 6 th sent_size  8<br/> 6 th read...read_size is not 20 and it is 8<br/>
    Second file sent</p>
  </blockquote>
  
  <p>As seen in the Client's output the 6th read from the file is only 15 bytes,so the client is sending 15 bytes. After that, a flag ("done") is sent (which i am not counting). At the Server's output the 6th read size should have been 15. But its reading the flag along with the data.</p>