Remoting socket address not released after service is stoped

  • Thread starter Thread starter Stephen
  • Start date Start date
S

Stephen

We are using .net remoting in our application. We have an issure on one of
our application installations. When we stop the service, the socket address
that was used by this service is not released. Then we try to start this
service, we will get an exception -- Service cannot be started.
System.Runtime.Remoting.RemotingException: Remoting configuration failed with
the exception 'System.Reflection.TargetInvocationException: Exception has
been thrown by the target of an invocation. --->
System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted
at
System.Runtime.Remoting.Channels.Http.HttpServerChannel.StartListening(Object
data)
at System.Runtime.Remoting.Channels.Http.HttpServerChannel.SetupChannel()
at
System.Runtime.Remoting.Channels.Http.HttpServerChannel..ctor(IDictionary
properties, IServerChannelSinkProvider sinkProvider)
at System.Runtime.Remoting.Channels.Http.HttpChannel..ctor(IDictionary
properties, IClientChannelSinkProvider clientSinkProvider,
IServerChannelSinkProvider serverSinkProvider)

Now we have to restart this computer every time in order to restart the
service.
What should I do to fix this issue? Another weirld thing is that this issue
only happens on one of our application installations. The service works fine
on other computers. Does it have anything to do with the OS?

We use code below to register the socket address.
RemotingConfiguration.Configure(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, false);

Is there anything wrong with the code itself?

Please help me look at this issue. It really bothers us.
Thanks very much
 
Stephen said:
We are using .net remoting in our application. We have an issure on one of
our application installations. When we stop the service, the socket address
that was used by this service is not released.

This should be impossible if your service process terminates, as the OS will
release the socket when that happens, regardless of whether it was properly
closed. Check if your service process has actually terminated (not merely
marked as "stopped"), there might be a hang.

To diagnose proper termination, run the service under a debugger and see
what keeps it from exiting if it does hang. Because you cannot start the
service as a service from within the debugger, you must either rewrite your
service's Main() so it supports running as a regular application (this is
easy, just test for Environment.UserInteractive) or you can attach to the
service as it is running through "Debug -> Attach to process" from within VS.
What should I do to fix this issue? Another weirld thing is that this issue
only happens on one of our application installations. The service works fine
on other computers. Does it have anything to do with the OS?
That's not likely, but it could certainly depend on the installation. Likely
culprits for interference are firewalls and other network tools that use
low-level hooks.
 
Jeroen said:
This should be impossible if your service process terminates, as the OS
will release the socket when that happens, regardless of whether it was
properly closed.

Closing the listening socket does not mean that the port it was bound
to immediately becomes free for binding again. Since the endpoint for
the server's listening socket is generally the tuple {tcp, *, port, *,
*}, that means there may be a period after the socket is closed when
no process (say, a new instance of the server) can bind to it.

In particular, in various cases (eg when a local client was connected
to the server when it was shut down), you'll have a connection in
TIME_WAIT state blocking the port from being bound again. That state
times out eventually (hence the name), and when it does (for all
connections to that port) you'll be able to bind again.

(In Windows, the duration of the TIME_WAIT state can be configured via
some Registry setting. Finding the setting in question and its default
value are left as an exercise for the reader. Note that setting it too
short is a Bad Idea; it's there for a reason.)

This is a well-known consequence of TCP's port-binding rules, and is
explained at length in reference works such as Stevens' _TCP/IP
Illustrated_. It's also covered in the Unix Socket FAQ (question 4.1)
and indirectly in the Winsock FAQ (question 4.13).

It's a good idea to read the FAQs and at least have a good
comprehensive reference at hand when writing a TCP/IP application. Not
everything about TCP/IP is intuitive or immediately apparent to the
new practitioner.
 
Michael said:
Closing the listening socket does not mean that the port it was bound
to immediately becomes free for binding again. Since the endpoint for
the server's listening socket is generally the tuple {tcp, *, port, *,
*}, that means there may be a period after the socket is closed when
no process (say, a new instance of the server) can bind to it.
Though I know about TIME_WAIT, I didn't actually think that could cause a
bind failure -- at least not with a "socket is already in use" error.

But you are, of course, completely right that the socket may not be
gracefully closed, so it has to linger. The interesting thing is that I've
never seen this happen for managed applications, because the framework
gracefully closes it as part of disposing. On the other hand, that's not
guaranteed to succeed.
 
Back
Top