.NET Framework Developer Center > .NET Development Forums > Network Class Library (System.Net) > TcpListener: Accept queued connections after Stop()
Ask a questionAsk a question
 

Proposed AnswerTcpListener: Accept queued connections after Stop()

  • Monday, October 26, 2009 6:50 PMjar349 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    When Start() is called on an instance of TcpListener, it begins to queue pending connections, which my application can dequeue (one-by-one) by calling AcceptTcpClient().  Additionally, and this is important, the MSDN documentation for the TcpListener class states that when Stop() is called, it does not do anything with any already-queued but unaccepted connections.  I cannot see any way to do the following:

    1. Call Stop() on the instance of TcpListener so that it will stop listening for and queueing future connections.
    2. Allow me to AcceptTcpClient() on the instance so that I can handle the internally queued but as-of-yet unaccepted connections before terminating my executable.
    3. Or, forcefully close the queued, unaccepted connections within my TcpListener instance so that they do not remain open and cause my executable's port to remain bound until the client closes its connection.

    I have run into an issue where a very busy executable is shutdown, which correctly causes my code to call Stop() on its TcpListener and cleanly exit the while loop that checked for Pending() connections.  However, that TcpListener had queued, unaccepted connections which caused the port to remain bound even after the executable terminated - making it impossible to restart the executable since its port is still bound.

    If this is possible using the System.Net.Sockets.Socket class, I'd be happy to switch over, but I don't see anything terribly promising there either.

All Replies

  • Tuesday, October 27, 2009 1:25 AMFeroze Daud Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    The fact that you cannot bind to the same port after restarting the app has to do with the TCP state machine. TCP will put the port in a TIME_WAIT state, so that will prevent it being used again for a certain period of time (which is customizable).

    One way you can force a bind is to set the SocketOption.ReuseAddress option on the underlying socket. That should allow you to bind to the existing port.

    feroze
    --
    My blog
    Instruction on how to create a tracelog with your System.Net application
  • Tuesday, October 27, 2009 8:34 PMjar349 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    The fact that you cannot bind to the same port after restarting the app has to do with the TCP state machine. TCP will put the port in a TIME_WAIT state, so that will prevent it being used again for a certain period of time (which is customizable).

    One way you can force a bind is to set the SocketOption.ReuseAddress option on the underlying socket. That should allow you to bind to the existing port.

    feroze
    --
    My blog
    Instruction on how to create a tracelog with your System.Net application

    Setting this option allows my executable to bind on the port, as you said it would.  The problem is that now netstat shows that the System process is ALSO bound to the port, and connection attempts to my executable still fail.
  • Tuesday, October 27, 2009 10:51 PMFeroze Daud Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I am curious about the statement where you said that the docs say that the queued connections remain around after calling stop...

    According to the docs for TcpListener.stop (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.stop.aspx)

    Stop closes the listener. Any unaccepted connection requests in the queue will be lost. Remote hosts waiting for a connection to be accepted will throw a SocketException . You are responsible for closing your accepted connections separately.

    Note Note:

    This member outputs trace information when you enable network tracing in your application. For more information, see Network Tracing .

    Notes to Callers:

    The Stop method also closes the underlying Socket , and creates a new Socket for the TcpListener . If you set any properties on the underlying Socket prior to calling the Stop method, those properties will not carry over to the new Socket .

     


    feroze
    --
    My blog
    Instruction on how to create a tracelog with your System.Net application
  • Wednesday, October 28, 2009 1:18 AMjar349 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed Answer
    That's true, but look at the documentation for the TcpListener class in general and you'll read:
    Note Note:

    The Stop method does not close any accepted connections. You are responsible for closing these separately.


    • Proposed As Answer byFeroze Daud Friday, October 30, 2009 3:18 PM
    •