meta data for this page
  •  

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
courses:ct30a5002:tcprecvsend [2013/09/23 18:51]
julaakko
courses:ct30a5002:tcprecvsend [2015/11/04 11:49] (current)
julaakko
Line 1: Line 1:
 +===== Making sure that all data is sent and received with TCP =====
  
 +A example when all is sent in one call, e.g. in client ([[http://​beej.us/​guide/​bgnet/​output/​html/​multipage/​advanced.html#​sendall|another one]]):
 +<code c>
 +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;
 +}
 +</​code>​
 +
 +
 +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:
 +<code c>
 +
 +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
 +
 +</​code>​
 +
 +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 {{:​courses:​ct30a5000:​tcptest.tar.gz|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 <​code>​./​tcptestc <​serverIP>​ <server port></​code>​ and the server with <​code>​./​tcptests <​port></​code>​
 +
 +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.
 +
 +
 +----
 +[[courses:​ct30a5002:​start#​code_snippets|CT30A5002 - Games and Networking]]