TcpListener是否正在侦听的属性/方法是什么?

13

目前我正在做类似于这样的事情:

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

        isListening = true;
    }
}

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

        isListening = false;
    }
}

在TcpListener中是否有一种方法或属性可以确定TcpListener是否已经开始监听(即是否调用了TcpListener.Start())?如果还没有开始,就不能真正访问TcpListener.Server,因为它尚未实例化。即使我能够访问它,我也不确定它是否包含一个Listening属性。

这真的是最好的方法吗?


1
你怎么可能不知道你自己的代码已经调用了Start()函数呢?请再仔细思考一下。 - Hans Passant
@HansPassant:有一个用户界面。当用户在Windows表单上单击“开始”按钮时,将调用Start。 - Ryan Peschel
谁编写了Click事件处理程序的代码?不是你吗?更大的问题是:为什么用户想要点击一个按钮? - Hans Passant
@HansPassant:这只是我正在开发的一个简单库的示例表单。我仍然不明白我应该如何“知道”它正在侦听。布尔检查的目的是为了防止在已经启动时重新启动它或在已经停止时停止它。 - Ryan Peschel
只有一种有用的TcpListener:正在监听的那个。任何未在监听的TcpListener对象都是浪费空间。您将知道它正在监听,因为该对象不为null。创建TcpListener对象而不调用其Start()方法是没有意义的。 - Hans Passant
在创建TcpListener之前,您无法创建套接字。当TcpListener被实例化时,套接字总是会被创建。 - Rowan Smith
2个回答

33

TcpListener实际上有一个名为Active的属性,可以完全满足您的需求。但是,由于某种原因,该属性被标记为受保护,因此除非从TcpListener类继承,否则无法访问它。

通过向项目添加一个简单的包装器,您可以解决这个限制。

/// <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; }
    }
}

您可以使用它来代替任何TcpListener对象。
TcpListenerEx tcpListener = new TcpListenerEx(localaddr, port);

2

您可以直接从Socket获取此内容。当TcpListener被实例化时,将始终创建一个Socket。

        if(tcpListener.Server.IsBound)
            // The TcpListener has been bound to a port
            // and is listening for new TCP connections

只是额外的注释。你也可以尝试 ClientSession.listener != null... 特别是如果你正在使用按钮初始化 ClientSession.listener - Jonas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接