tags:

views:

196

answers:

3

I'm trying to stop a TCP Listener as my program is exiting. I do not care about any data that is currently active on the socket or any of the active client sockets.

The socket clean up code is essentially:

try
{
    myServer.Server.Shutdown(SocketShutdown.Both)
}
catch (Exception ex)
{
     LogException(ex)
}
myServer.Server.Close(0)
myServer.Stop()

myServer is a TCPListener

On some occasions, Shutdown will thrown an exception

System.Net.Sockets.SocketException: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied at System.Net.Sockets.Socket.Shutdown(SocketShutdown how)

Edit 2010-May-14

Upon further investigation, the exception can be thrown and the socket can be closed correctly.

Sometimes, even after the application exits netstat shows the socket is still in the LISTENING state.

I have not been able to create definitive reproduction scenario, it happens at seemingly random times.

Client Sockets are cleaned up independently.

Do you have any suggestions to help me make this socket die?

+1  A: 

Try calling Stop before Close...

paquetp
A: 

After your app exits, the socket cannot be in a listening state. It may be in a wait state, however; this is perfectly normal.

Stephen Cleary
Application no longer shows up in Task Manager. PID associated with the socket is not related to any process in task manager. Connection State according to netstat LISTENING three hours after the application has exited.
lnical
I have the program exited and the socket currently listening on right now. If there is any more information you would like, please let me know.
lnical
Could you verify using [Process Explorer](http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) and [TCPView](http://technet.microsoft.com/en-us/sysinternals/bb897437.aspx)? TCPView should give the same result as netstat, but Process Explorer is more exhaustive than Task Manager.
Stephen Cleary
TCPView shows the same information as netstat in a easier to read format. Thanks for reminding me. It shows <non-existent>:3580 TCP PCNAME:19000 PCNAME:0 LISTENING. Process Explorer shows the executable is not running.
lnical
Hmmm... The only thing I can think of is something messing with the kernel process structures. A lot of viruses do this. Could also be a network driver bug. I'd check for updates at least. It's definitely not correct behavior - on the part of the OS/drivers, I mean. :)
Stephen Cleary
The error occurs on multiple devices in different locations. I'm not sure this is an OS level issue. Each machine is prepped similar to the other.
lnical
It still doesn't sound right to me. It is the OS's responsibility to close handles when a process is terminated; in the case of connected sockets, it may enter a wait state for a short time before it's actually closed, but listening sockets should be closed immediately. Exceptions, GC, disposing, and all that doesn't even matter - if your process actually exits, it's the OS's job to clean up...
Stephen Cleary
+2  A: 

Use a finally block to call Close() in the event of an exception:

try
{
    myServer.Server.Shutdown(SocketShutdown.Both);
}
catch (Exception ex)
{
    LogException(ex);
}
finally
{
    myServer.Server.Close(0);
    myServer.Stop();
}

I'm also curious if manipulation of the underlying socket is required because of some specification you haven't mentioned? TCPListener/Client are designed you keep you from worrying about those communication mechanics in most cases.

Also, if this doesn't help, what ErrorCode is being returned by the SocketException?

Sorax
The Socket Shutdown was added because of this open socket after program exit. In some instances (not all, and not entirely reproducible) the socket remains open in a listening state.In the production code, the close and stop commands are wrapped in another try-catch-finally construct with more logging. Those commands are not throwing an exception.Judging by the error code I believe the error code is WSAENOTCONN10057.Upon further research, at other times the shutdown error is thrown and the socket closes normally. I'll edit the main question to add that information.Thanks.
lnical
Thinking of possible solutions has me wondering if the client is the cause. The socket's Dispose is a response to the client's close. So the socket's orphaned state could be a symptom of a client not correctly disconnecting. Is the client's connection and disconnection designed in a relatively atomic manner?I also think tracing could help reveal the issue. Check out this link on setting it up, if you haven't already: http://2.ly/3K2I'd write instructions but I don't have enough characters left. It'll require some sifting but tracing should reveal where the communication break down occurs.
Sorax