2

I have an IIS 6.1 application in which I am attempting to maintain a socket server but I can't free the port:

In Global.asax.cs Application_Start I start a thread ProgramConnectionServerThread in which I've got:

int programPort = ServerConfiguration.Instance.ProgramConnectionPort;
ServerConfiguration.Instance.ProgramConnectionSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket listener = ServerConfiguration.Instance.ProgramConnectionSocket;
IPEndPoint localEndPoint = new IPEndPoint(Dns.Resolve(Dns.GetHostName()).AddressList[0], programPort);

listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
    Socket handler = listener.Accept();
    // action
}

and in Global.asax.cs Dispose

try
{
    if (ServerConfiguration.Instance.ProgramConnectionServerThread != null)
    {
        ServerConfiguration.Instance.ProgramConnectionServerThread.Abort();
    }
}
catch (Exception eeg2)
{
// Log
}
try
{
    LingerOption lo = new LingerOption(false, 0);
    ServerConfiguration.Instance.ProgramConnectionSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
    ServerConfiguration.Instance.ProgramConnectionSocket.Shutdown(SocketShutdown.Both);
    ServerConfiguration.Instance.ProgramConnectionSocket.Close(); // this is Line 133
}
catch (Exception eeg2)
{
// Log
}

This approach does not seem to be working. In my logging I get the following error message on the Close() invocation:

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)
   at Contoso.Global.Dispose() in E:\Contoso\Global.asax.cs:line 133

If I restart the web site in IIS the port is not free! I get this message when I do the bind:

System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted

How do I free this port so on subsequent restarts of the application I can bind a new listener?

Mishax
  • 4,442
  • 5
  • 39
  • 63

1 Answers1

2

I have seen the line numbers to be off by one sometimes. The stack trace clearly tells you it came from Shutdown.

A listening socket is never connected. Why are you shutting it down? Make sure you understand what Shutdown does.

Do not abort threads.

Using an ASP.NET app as a socket server is hard to get right. Worker process lifetimes can overlap, as you probably have observed. That would be a new question however.

Community
  • 1
  • 1
usr
  • 168,620
  • 35
  • 240
  • 369
  • 1
    Right so the reason I am trying to shut it down is because of the error I get saying "Only one usage of each socket address...is normally permitted". The second time I try to bind a socket server to that address, it fails and I'm thinking this must be due to the old Socket still being blocked in its call to `Accept()`. The whole reason I'm trying all this stuff is to free that port so I can bind to it again. Can you tell me how? If there was a method called "Unbind" I would call it. – Mishax Sep 17 '14 at 16:24
  • Close is that method. As I said, multiple worker processes can exist at the same time. Try retrying for a few seconds hoping that the old worker is shut down by then. You are working against the system here. You're not supposed to host things in IIS of which there can only be at most one instance at the same time. You surely can make it work but expect trouble. Also, try not to use sockets at all. – usr Sep 17 '14 at 16:53
  • Ok then it seems some advice I've been following in other SO posts is incorrect. What I've done is (1) *not* drop the thread (2) *do* keep the LingerOption as before (3) *not* disconnect the server socket (4) *do* close the socket and (5) catch the SocketException that will be thrown while the thread is blocked in the Accept() method. Then it seems to work. – Mishax Sep 18 '14 at 10:09
  • Yes, that's correct. Except that the linger option does nothing for listening sockets. Let me point out that most socket advice on the web is questionable. Hardly anyone understands sockets well. That's why they should only be used if no other option is available. – usr Sep 18 '14 at 10:45