meta data for this page
  •  

Making sure that all data is sent and received with TCP

A example when all is sent in one call, e.g. in client (another one):

int write_to_socket(int sockfd, char* data, unsigned int data_len, unsigned int *data_written)
{
  int wrote = 0;
 
  // Initialize the pointer value to 0
  *data_written = 0;
 
  // While we have something to write
  while(*data_written < data_len)
  {
    // Write remaining data
    if((wrote = send(sockfd,&data[*data_written],data_len - *data_written,0)) <= 0) return -1;
 
    // Update the written amount for pointer
    *data_written += wrote;
  }
 
  return 1;
}

For receiving data you have to use a different approach, especially with multiple connections. If the data is not received in one recv call keep reading until the full packet is completely read. One example:

int read_from_socket(int sockfd,char* buffer, unsigned int total, unsigned int *remaining)
{
  do
  {
    // Read 0 or less -> we're done here, return -1 or 0
    if((data_read = recv(sockfd,&buffer[total-*remaining],*remaining)) < 1) return data_read;	
 
    // otherwise update the remaining amount
    else *remaining -= data_read;
 
  } while (*remaining > 0)
 
  return 1; //ok
} 

Just keep in mind that when designing the reading approach for a server it is good way to balance the load by reading only certain amount of data per client and then checking if it is fully received. If not, proceed to the next client and so on.

A demonstration server and client using MSG_DONTWAIT flag with send. Client sends a 1 Mb of data to the server and both quit after the data is sent full / all is received. Compile with make and run the client with

./tcptestc <serverIP> <server port>

and the server with

./tcptests <port>

The MSG_DONTWAIT demonstrates the effect when the send buffer is full and the application cannot write more → the function returns and in next round attempts to write more into the buffer. Without the flag the send() function blocks until all requested data is sent - it will fill the buffer, wait until there is space, fill the remaining space, wait .. and it continues until all is sent.


CT30A5002 - Games and Networking