TCP/IP port not released?

Started by
6 comments, last by yahastu 14 years, 10 months ago
My server application creates a thread, and in this thread I listen and connect to the client. source:

//create listener socket
		conn->sListen = socket( AF_INET, SOCK_STREAM, 0 );
		if (conn->sListen == INVALID_SOCKET) {
			out << "Error trying to create ClientListen socket: " << heinlib::GetLastErrorMessage() << "\n";
			return false;
		}

		struct sockaddr_in service;
		service.sin_family = AF_INET;
		service.sin_addr.s_addr = INADDR_ANY;
		service.sin_port = htons(conn->port);

		if ( bind(conn->sListen, (SOCKADDR*)&service, sizeof(service) ) == SOCKET_ERROR )
		{
			out << "Unable to bind ClientListen socket (port " << conn->port << "): " << heinlib::GetLastErrorMessage() << "\n";
			return false;
		}


conn->port is fixed at 4205 ...I always wait on the same port, because I only allow 1 client connection. This has never been a problem before. I restart the server many times during testing..sometimes force-quitting it without any problems restarting it later. This time, I get an error when trying to restart it:
Quote: Unable to bind ClientListen socket (port 4205): Only one usage of each socket ad dress (protocol/network address/port) is normally permitted.
But the server process has been terminated! I've been trying this over a period of time and the error won't go away. I assume it will go away if I restart, but I haven't yet, because I want to figure out why it's happening. When I look at my netstat report, looks like the port is not in use:
Quote: C:\Windows\system32>netstat -b Active Connections Proto Local Address Foreign Address State TCP 127.0.0.1:49352 Urza:49353 ESTABLISHED [firefox.exe] TCP 127.0.0.1:49353 Urza:49352 ESTABLISHED [firefox.exe] TCP 127.0.0.1:49354 Urza:49355 ESTABLISHED [firefox.exe] TCP 127.0.0.1:49355 Urza:49354 ESTABLISHED [firefox.exe] TCP 192.168.1.3:63644 verne:6667 ESTABLISHED [mirc.exe] TCP 192.168.1.3:64798 gy-in-f104:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64799 gy-in-f102:http CLOSE_WAIT [firefox.exe] TCP 192.168.1.3:64808 65.55.11.235:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64809 65.55.11.235:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64811 rdc-024-025-026-058:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64812 rdc-024-025-026-058:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64813 rdc-024-025-026-058:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64815 65.55.11.235:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64816 65.55.11.235:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64817 65.55.11.235:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64818 65.55.11.235:http ESTABLISHED [firefox.exe] TCP 192.168.1.3:64819 rdc-024-025-026-026:http ESTABLISHED [firefox.exe] C:\Windows\system32>netstat -n Active Connections Proto Local Address Foreign Address State TCP 127.0.0.1:49352 127.0.0.1:49353 ESTABLISHED TCP 127.0.0.1:49353 127.0.0.1:49352 ESTABLISHED TCP 127.0.0.1:49354 127.0.0.1:49355 ESTABLISHED TCP 127.0.0.1:49355 127.0.0.1:49354 ESTABLISHED TCP 192.168.1.3:63644 216.155.130.130:6667 ESTABLISHED TCP 192.168.1.3:64869 74.125.157.165:80 ESTABLISHED TCP 192.168.1.3:64870 74.125.157.156:80 ESTABLISHED TCP 192.168.1.3:64877 74.125.157.102:80 ESTABLISHED TCP 192.168.1.3:64879 63.245.209.93:80 CLOSE_WAIT TCP 192.168.1.3:64880 63.245.209.93:80 CLOSE_WAIT TCP 192.168.1.3:64881 212.58.226.138:80 TIME_WAIT C:\Windows\system32>
UPDATE - using TcpView.exe I was able to detect it,
Quote: <non-existent>:1256 TCP Urza:4205 Urza:0 LISTENING
That first part, "non-existant" means that there is no process using it...this seems to be a network stack bug. Is there any way this is my fault? [Edited by - yahastu on June 8, 2009 1:36:49 PM]
Advertisement
Quote:Original post by yahastu
conn->port is fixed at 4205 ...I always wait on the same port, because I only allow 1 client connection. This has never been a problem before. I restart the server many times during testing..sometimes force-quitting it without any problems restarting it later.


For TCP, you always listen on same port. When you accept a connection, new socket is provided for you through which you communicate. This can be one or many, it doesn't affect the server socket.

Quote:C:\Windows\system32>netstat -b


What about netstat -ba? I also like to use -na for a quick dump.

Your server socket will be in LISTENING mode (for port 4205), if it somehow survived. Client connections will only appear once established.

Quote:Is there any way this is my fault?


Meh, blame MS.

I don't remember encountering hanging sockets (on recent Windows versions), but it may have something to do with various firewalls or similar.

Sysinternals has many utilities, the process monitoring ones may allow you to kill that particular socket.
Terminating a listener without closing the socket may end in a dangling socket. The kernel polls open sockets for life (every 60 seconds on linux, on DOS/NT it's going to be similar) and frees any sockets without a live process attached to it.

So no, it's not your fault, it's how it's supposed to work.

To avoid problems with it I suggest you add an explicit close() to your shutdown function and/or sigterm handler (or whatever you guys use on windows to kill processes with).
Quote:Original post by tori
Terminating a listener without closing the socket may end in a dangling socket. The kernel polls open sockets for life (every 60 seconds on linux, on DOS/NT it's going to be similar) and frees any sockets without a live process attached to it.

So no, it's not your fault, it's how it's supposed to work.


Except this socket had been dangling for over an hour with no associated process, and there was no way to close the connection without restarting the computer

Quote:To avoid problems with it I suggest you add an explicit close() to your shutdown function and/or sigterm handler (or whatever you guys use on windows to kill processes with).


The server is an event-driven command line application, I can login to the server and tell it to shut down, that should work, but I don't think there's any way I can catch the event in which "ctrl+c" is pressed or the process is otherwise aborted, to safely call closesocket()
setsockopt SO_REUSEADDR?
Quote:Original post by yahastu
The server is an event-driven command line application, I can login to the server and tell it to shut down, that should work, but I don't think there's any way I can catch the event in which "ctrl+c" is pressed or the process is otherwise aborted, to safely call closesocket()


SetConsoleCtrlHandler.

A quick google shows some examples as well, their quality may vary.
Oh, if it's hanging in there for more than a couple of seconds it's kernel's problem. File a bug report because that shouldn't be happening.
totally agree with samoth

setsockopt SO_REUSEADDR

moreover, it is strongly recommended using this option for server:)
Antheus and Samoth,

Thank you both for those excellent tips!

This topic is closed to new replies.

Advertisement