Thursday, April 10, 2008

Proper way to close TCP socket

This question arises very often in the developers communities.
For simplification I'll talk about synchronous sockets.

Generally, the procedure is like this:

  1. Finish sending data

  2. Call Socket.Shutdown with SocketShutdown.Send parameter

  3. Loop on Receive until it returns 0 or fails with an exception

  4. Call Close()

Here's a small sample in pseudo code that is very similar to C# :)

void CloseConnection(Socket socket)
{
socket.Send(/*last data of the connection*/);
socket.Shutdown(SocketShutdown.Send);

try
{
int read = 0;
while( (read = socket.Receive(/*application data buffers*/)) > 0 )
{}
}
catch
{
//ignore
}
socket.Close();
}

If first and third steps are skipped - data loss can happen.

Things become more complicated when using asynchronous sockets.
To prevent data loss while closing connection: termination logic can be added to the data exchange protocol.
For example, it can be some kind of termination message (depends on data protocol). When peer receives message of this kind, it can proceed with connection termination logic described above.

Another way is to put socket in a blocking mode (if socket was in non blocking mode) and close the connection in the way described above.

When designing network application one has to think also about its connection closing procedure. The purpose of proper connection close is prevention of data loss.

0 коментарі: