locked
SocketException when registering channel: Possible bug in .NET Remoting RRS feed

  • Question

  • When registering and unregistering a TCP channel repeatedly, I often get a SocketException.  It seems as though UnregisterChannel does not truly stop the TCP socket and unregister everything.  The code below reproduces on my system.  Am running .NET Framework 2.0 RTM / Visual Studio 2005 and no beta code was ever installed on this machine.  The problem reproduces on two other machines but not a third.

      public static void Main(string[] args) {
       int i = 1;
       try {
        while (true) {
         ChannelServices.RegisterChannel(new TcpChannel(666), false);
         ChannelServices.UnregisterChannel(ChannelServices.RegisteredChannels[0]);
         i++;
        }
       } catch (Exception ex) {
        Console.WriteLine("Died at iteration {0}.", i);
        Console.WriteLine(ex.ToString());
        Console.ReadLine();
       }
      }

    The output on my machine is:

    Died at iteration 4.
    System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
       at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
       at System.Net.Sockets.Socket.Bind(EndPoint localEP)
       at System.Net.Sockets.TcpListener.Start(Int32 backlog)
       at System.Net.Sockets.TcpListener.Start()
       at System.Runtime.Remoting.Channels.ExclusiveTcpListener.Start(Boolean exclusiveAddressUse)
       at System.Runtime.Remoting.Channels.Tcp.TcpServerChannel.StartListening(Object data)
       at System.Runtime.Remoting.Channels.Tcp.TcpServerChannel.SetupChannel()
       at System.Runtime.Remoting.Channels.Tcp.TcpServerChannel..ctor(Int32 port)
       at System.Runtime.Remoting.Channels.Tcp.TcpChannel..ctor(Int32 port)
       at CrashMe.Program.Main(String[] args)

    It never fails on the first iteration.  Sometimes it fails on the 2nd iteration, or, as in this case, it may work a little longer and then die.  On one machine it died at the 162 iteration on first run - the hard drive was quite active.  After that it usually died on the 2nd iteration.

    The problem appears to be timing related.  If I add a "Thread.Sleep(100);" to the loop after the call to UnregisterChannel, it does not crash.  Of course, this is not really an acceptable solution or workaround since in a production environment you cannot guarantee that your sleep interval will always work right!

    Is there some way to get UnregisterChannel to immediately close instead of trying to do things in the background behind my back?

    Thanks for any help!

    Best regards,

    James Johnston

    Thursday, July 20, 2006 8:38 PM

Answers

  • Hi folks, Unregistering the service doesn't force a synchronous freeing of resources; instead, it marks the underlying structures as "available for cleanup".  Given that, the actual timing of the cleanup will vary depending on system load, number of processors, etc.  If you're going to be repeatedly stopping a and starting a service you'll need to 1) wait a few seconds before you startup and 2) if you see the SocketException, catch it, wait, and retry (a finite number of times in case you have a non-transient problem).

    Cheers,

    JJustice [MSFT]

    Friday, August 11, 2006 9:09 AM
    Moderator

All replies

  • It doesn't happen on my machine. Anyway, I think that this is related to how the underlying sockets work and there is not much you can do about it. Why are you trying to use channels this way? I'm sure they were not designed for this usage.
    Friday, July 21, 2006 9:30 AM
    1. It is a Windows service that can dynamically reconfigure itself.
    2. Register/UnregisterChannel are being called from tests in NUnit (and the calls are not being made directly from the test fixture, but from the Windows service which is being tested).  So they get called repeatedly.  I've had problems with tests mysteriously failing and was able to trace it to this bad UnregisterChannel behavior.
    Friday, July 21, 2006 5:35 PM
  • I have the same issue with RemotingConfiguration.Configure in a Windows Service.

     

    1. Start the service and call RemotingConfiguration.Configure.

    2. Stop the service.

    3. Start the service and get "System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.".

    If I wait a few seconds the service starts fine.

     

    Thursday, July 27, 2006 2:33 PM
  • Hi folks, Unregistering the service doesn't force a synchronous freeing of resources; instead, it marks the underlying structures as "available for cleanup".  Given that, the actual timing of the cleanup will vary depending on system load, number of processors, etc.  If you're going to be repeatedly stopping a and starting a service you'll need to 1) wait a few seconds before you startup and 2) if you see the SocketException, catch it, wait, and retry (a finite number of times in case you have a non-transient problem).

    Cheers,

    JJustice [MSFT]

    Friday, August 11, 2006 9:09 AM
    Moderator
  • NA
    Thursday, January 18, 2007 9:05 PM
  •  

    I see this once in a while debugging new code that happens to be crashing my service.  Waiting doesn't clear the problem. It's permanently stuck.  This usually isn't a big deal, but today I'm on my third reboot b/c of this.  Is there any way to reset/free the port again so this exception goes away without a reboot?

     

    thanks,

    Dave

    Wednesday, February 28, 2007 1:01 AM
  • Is there a way to wait for the resources to be released or query the status to find out if it's really unregistered?
    Monday, August 6, 2007 3:22 PM
  • I am also having this same problem. Except I'm waiting for what seems like forever and the port is still not being released. I have unregistered the channel and manually called StopListening.

    Any ideas?

    Neil.
    Thursday, September 11, 2008 1:48 PM
  • The remoting is usually based on the TCP transport, which has a parameter called TIME_WAIT delay.
    This parameter controls for how long the underlying connection is kept in TIME_WAIT status for 30-300 seconds after the call to close it was placed. In short, it prevents from incorrect usage of closed connections. The details can be found at

     http://msdn.microsoft.com/en-us/library/ms819739.aspx

    According to RFC 793, the default value is 240 seconds, which is default settings in Windows 2003 Server TCP/IP stack.

    The workaround for high-performance systems is to implement the connection pool and instead of always allocating a new connection, reuse the existing ones.

    Hope this helps.

    Alexander Schmidt, MCPD
    • Edited by aschmidt Tuesday, September 16, 2008 7:24 PM
    • Proposed as answer by aschmidt Thursday, January 5, 2012 8:34 PM
    Tuesday, September 16, 2008 7:23 PM
  • How would one go about creating a connection pool for .Net remoting servers?  Is there an article I can read up on?

    Thank you!
    Hello World
    Wednesday, December 17, 2008 4:14 PM
  • sadasdasdas
    Monday, December 22, 2008 1:03 PM
  • Hi, may be can you help me

    1-I’ve developed a .net 2.0 remoting application.

    2-I’m using four Windows Services to host my remoting objects.

    3-I’m using TCP Channel and SAO activation.

    4-This is the Windows Services .app config

     <!-- CONFIGURACION SERVICIOS REMOTOS -->

           <system.runtime.remoting>

                <customErrors mode="off"/

                <application>

                      <channels>

                            <channel ref="tcp"  port="23501" 

                                     socketCacheTimeout="0"

                                        socketCachePolicy="absoluteTimeout">

                                 <serverProviders>

                                       <formatter ref="binary" typeFilterLevel="Full"/>

                                 </serverProviders>

                            </channel>

                      </channels>

     

                      <service>

     

     <wellknown mode="SingleCall" type="SAFI_NET.Negocios.Operaciones.Ordenes, SAFINET.Negocios.Operaciones" objectUri="Ordenes"/>

     

    5- This is the Client Activation

     

    CType(Activator.GetObject(GetType(Interfaces.Operaciones.ICierresDiarios), Aplicacion.TraerURLOperaciones & "/CierresDiarios"), Interfaces.Operaciones.ICierresDiarios)

     

    6-I have a Middleware farm (F5 BIGIP) address (192.168.162.162). This farm has two nodes (192.168.162.50, 192.168.162.51).This nodes has the same hardware and software specification. Both of them have installed my Windows Services.

    7-When I try to connect trough the farm , I get this error  “An  active connection was forcibly closed by remote host” or even :

     

    System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond Server stack trace: at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Connect(EndPoint remoteEP) at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEndPoint) at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket() at System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machinePortAndSid, Boolean openNew) at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithRetry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream) at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream) at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at

    8- I try to connect to a single node 192.168.162.50 OR 192.168.162.51 and I don’t get any error.

     

    Thanks for your help!

     

    Tuesday, March 31, 2009 2:06 PM