Hi,

Please let me know if this post doesn't belong here... I couldn't find a dedicated forum for network programming, so posted this here.

I'm developing a client and server for using Winsock/TCP/C++. I'm relatively new to network programming and have a few doubts :

  1. Suppose I send 8 bytes from the server in a single send( ), can I be sure that I will ALWAYS get 8 bytes in a single recv at client(assuming that I specify 8 bytes as my buffer size in recv)? The question is, is it possible (probably due to network conditions) that the client recv's 3 (or somethin else <8) bytes only first; and the rest of the 5 bytes at the next recv? In that case I'll have to do recv in loop until I get 8 bytes.
  2. As server resources are at a premium, I don't want to keep a connection idle for too long. I'm facing a dilemma on how to do this:
    When I detect a timeout I can simply close the socket, thereby releasing system resources. But if I do this, the client would have no clue that it was timed out.

    I also want to client to know that it has been timed out, for which I'll need to send a timeout message to the client and wait to make sure it has received it. But in this case, the socket will still be open, nullifying the whole purpose of timing out a client. Is there a way to timeout that meets both these criteria?

Thanks for the help!

1. recv() will NOT necessarily receive all the bytes sent in one call. You will have to loop it. Since recv() returns the number of bytes received, what you can do is have the sender always put an integer at the start of each message specifying the length of the message so that the receiver knows when to stop looping for that message. In addition, the same problem exists for the sender - send() is not guaranteed to send all the bytes requested in one call to send(), so you must loop that as well. It is probably best to make functions like recv_all() and send_all() that do this for you automatically so that you don't have to keep writing loops and checking sizes every time you want to send or receive a message.

2. If the client has called recv() and the server closes the socket, the client's recv() will return -1 signifying this. If the server closes the socket and the client tries to send() it will also receive an error. So either way the server can just close the connection and you can program the client to deal with this. You should program the client to handle this situation anyway in the case that the server crashes or something, so that the client doesn't crash as a result.

1. recv() will NOT necessarily receive all the bytes sent in one call. You will have to loop it. Since recv() returns the number of bytes received, what you can do is have the sender always put an integer at the start of each message specifying the length of the message so that the receiver knows when to stop looping for that message.

I do add the length of the message in the start of message, and thats what I want to read in recv (8 bytes)! I was wondering if its really necessary to loop just for 8 bytes.:-/

In addition, the same problem exists for the sender - send() is not guaranteed to send all the bytes requested in one call to send(), so you must loop that as well. It is probably best to make functions like recv_all() and send_all() that do this for you automatically so that you don't have to keep writing loops and checking sizes every time you want to send or receive a message.

As far as my interpretation of send( ) in MSDN goes, I believe send will send all the data if it succeeds for blocking, stream oriented sockets, which is what I'm using. The extract from MSDN:

If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode. On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers.

2. If the client has called recv() and the server closes the socket, the client's recv() will return -1 signifying this. If the server closes the socket and the client tries to send() it will also receive an error. So either way the server can just close the connection and you can program the client to deal with this. You should program the client to handle this situation anyway in the case that the server crashes or something, so that the client doesn't crash as a result.

If the connection is closed by the other end (using closesocket), recv returns 0 (indicating a graceful shutdown). I guess the client can interpret that to mean it has been timed out.

This article has been dead for over six months. Start a new discussion instead.