线程和C#中的TcpListener

本文关键字:TcpListener 中的 线程 | 更新日期: 2023-09-27 18:20:43

我需要编写一些使用TcpListener的代码。使用TcpListener的对象有三种可能:侦听、停止侦听、发送消息。我的代码是这样的:

public class someClass
{
    public bool listenerEnable {get; set; }
    public void StartListen()
    {
        .
        .
        .
        while (listenerEnable)
        {
            // Block until client connected
            TcpClient client = server.AcceptTcpClient();       
            // code that doing something with the client message ... 
        }
    }
}

现在,当我想停止侦听器状态(将listenerEnable更改为false)时,我不确定如何确保线程的安全。

此外,当我想在不停止服务器侦听器状态的情况下向客户端发送一些消息(以某种分离的方法)时,我不确定如何确保这个线程的安全。

谢谢你的帮助。

线程和C#中的TcpListener

我建议等待一个事件,而不是等待一个变量。在当前方案中,考虑循环测试侦听器变量是否为true的情况。如果是,它进入循环并等待传入连接,然后阻塞。因此,现在即使另一个线程将侦听器变量设置为false,您的循环也不会退出,直到有人连接到它并处理该连接。

解决上述问题的一种方法是使用以下代码:

WaitHandle[] waitHandles = new WaitHandle[] {endlLoopEvent};
while(true)
{
   int ret = WaitHandle.WaitAny(waitHandles, 100);
   if(WaitTimeout == ret) continue;
   else if(0 == ret) break; //our event has been signaled.
   else
    {
         if(!server.Pending()) continue; //Go back to the loop if no connection pending
         TcpClient client = server.AcceptTcpClient();  
         // You can spawn a thread to service the request.
    }
}

发送不会影响上面的循环,前提是它不是响应上面的连接请求。

编写一个正确的、可扩展的套接字服务器并不简单——我建议您找到/购买一个——以前已经做过很多次了。

要回答您的问题,您的问题是AcceptTcpClient是一个阻塞呼叫。您将希望使用以BeginXXXEndXXX开头的APM(异步编程模型)方法,如MSDN BeginAcceptTcpClient。

这些方法不会阻塞线程,但您必须处理并发性。