Detecting and terminating aborted TCP/IP connections | CodeGuru

Detecting and terminating aborted TCP/IP connections

Figure 1: Chat Server and Chat Client Environment: VC5 SP3, NT4 SP3 When one side of the TCP-IP connection goes down abruptly without notifying the other end, the other end is left hanging. This is especially important for a server handling hundreds of connections. For such a server, even a single hanging socket is tantamount […]

Written By
CodeGuru Staff
CodeGuru Staff
Jul 27, 1999
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More


Figure 1: Chat Server and Chat Client

Environment: VC5 SP3, NT4 SP3

When one side of the TCP-IP connection goes down abruptly without notifying the other end, the other end is left hanging.
This is especially important for a server handling hundreds of connections. For such a server, even a single hanging socket
is tantamount to wasting precious resources.
Winsock does not provide a function which directly checks for abrupt termination of the TCP/IP connection at the other end.

The function HasConnectionDropped checks if the other end of the socket is still connected.

The pseudo code is:

[1] Check if the socket is readable.

[2] If yes, peek at the incoming data.

[3] Check the return values, error values to see if the network connection is still up.

It is important that we just peek at the incoming data. The MSG_PEEK flag does just that.
The data is copied into the buffer but is not removed from the input queue. Thus we ensure that we do not disturb the functionality of the system.

We check the error values in case the recv call returns an error. Note that, if the recv call returns 0, it signifies a graceful disconnect from the other side.
Hence, we consider a 0 return value as an indication of dropped connection.


As an example, consider the ChatServer and Chatter client example from MSDN. Communication between the client and server is via CMsg objects. A CMsg object contains two members:
m_bClose: To signify that the connection is being closed.
m_strText: The text to be posted on to the chat server.


In case of a normal termination, the client sends a message with m_bClose set to TRUE. The server closes down it’s end of the connection on receiving this message and sends a close message to the client.
The client closes down it’s end after receiving this message.
So far so good. However, if the client terminates abruptly without sending the close message, the corresponding end at the server is never closed until the server shuts down.

I have modified the examples to illustrate the use of the HasConnectionDropped function.

On the server side, the menu handler for the menu item “Check Connections” iterates over the list of client connections to check if all connections are still up. Any client sockets for dropped connections are flushed out.

On the client side, the menu handler for the menu item “Kill myself” kills the client without giving it a chance to send a “Close” message to the server.

To run the demo:

[1] Start the server.

[2] Start one or more clients.

[3] Kill one (or more) client(s) by clicking “Kill myself” menu item.
Note that, a message saying “xyz has left the discussion” does not appear on the board. We do have a hanging connection here!

[4] Click on “Check connections”. A messagebox pops up showing the number of connections that were closed because they were dropped from the other side.

Note: I have written the function HasConnectionDropped to be a member of the CClientSocket (which depends upon the CSocket MFC class) to illustrate this technique.
However the function does not depend on any CSocket/MFC/Windows functionality. Basic Winsock functions select and recv are used.
Hence one can easily adapt this function to work in a non-MFC raw Winsock environment. The only change that has to be made is to accept the socket handle as a function parameter. (instead of as a member variable as in the present case)

BOOL CClientSocket::HasConnectionDropped( void )
{
	BOOL bConnDropped = FALSE;
	INT iRet = 0;
	BOOL bOK = TRUE;
	struct timeval timeout = { 0, 0 };
	fd_set readSocketSet;
	FD_ZERO( &readSocketSet );
	FD_SET( m_hSocket, &readSocketSet );
	iRet = ::select( 0, &readSocketSet, NULL, NULL, &timeout );
	bOK = ( iRet > 0 );
	if( bOK )
	{
		bOK = FD_ISSET( m_hSocket, &readSocketSet );
	}
	if( bOK )
	{
		CHAR szBuffer[1] = “”;
		iRet = ::recv( m_hSocket, szBuffer, 1, MSG_PEEK );
		bOK = ( iRet > 0 );
		if( !bOK )
		{
			INT iError = ::WSAGetLastError();
			bConnDropped = ( ( iError == WSAENETRESET ) ||
				( iError == WSAECONNABORTED ) ||
				( iError == WSAECONNRESET ) ||
				( iError == WSAEINVAL ) ||
				( iRet == 0 ) ); //Graceful disconnect from other side.
		}
	}
    return( bConnDropped );
}

Downloads

Download demo project – 6 Kb

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.