Is there a property/method for determining if a TcpListener is currently listening?

Ryan Peschel picture Ryan Peschel · Oct 3, 2011 · Viewed 10.5k times · Source

Currently I'm doing something like this:

public void StartListening()
{
    if (!isListening)
    {
        Task.Factory.StartNew(ListenForClients);

        isListening = true;
    }
}

public void StopListening()
{
    if (isListening)
    {
        tcpListener.Stop();

        isListening = false;
    }
}

Is there not a method or property within TcpListener to determine if a TcpListener has started listening (ie TcpListener.Start() was called)? Can't really access TcpListener.Server because if it hasn't started, it has not been instantiated yet either. Even if I could access it I'm not sure even that contains a Listening property.

Is this really the best way?

Answer

im_nullable picture im_nullable · Oct 22, 2011

The TcpListener actually has a property called Active which does exactly what you want. However, the property is marked protected for some reason so you cannot access it unless you inherit from the TcpListener class.

You can get around this limitation by adding a simple wrapper to your project.

/// <summary>
/// Wrapper around TcpListener that exposes the Active property
/// </summary>
public class TcpListenerEx : TcpListener
{
    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Net.Sockets.TcpListener"/> class with the specified local endpoint.
    /// </summary>
    /// <param name="localEP">An <see cref="T:System.Net.IPEndPoint"/> that represents the local endpoint to which to bind the listener <see cref="T:System.Net.Sockets.Socket"/>. </param><exception cref="T:System.ArgumentNullException"><paramref name="localEP"/> is null. </exception>
    public TcpListenerEx(IPEndPoint localEP) : base(localEP)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Net.Sockets.TcpListener"/> class that listens for incoming connection attempts on the specified local IP address and port number.
    /// </summary>
    /// <param name="localaddr">An <see cref="T:System.Net.IPAddress"/> that represents the local IP address. </param><param name="port">The port on which to listen for incoming connection attempts. </param><exception cref="T:System.ArgumentNullException"><paramref name="localaddr"/> is null. </exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="port"/> is not between <see cref="F:System.Net.IPEndPoint.MinPort"/> and <see cref="F:System.Net.IPEndPoint.MaxPort"/>. </exception>
    public TcpListenerEx(IPAddress localaddr, int port) : base(localaddr, port)
    {
    }

    public new bool Active
    {
        get { return base.Active; }
    }
}

Which you can use in place of any TcpListener object.

TcpListenerEx tcpListener = new TcpListenerEx(localaddr, port);