C#中的Thread和TcpListener

时间:2012-01-18 10:18:13

标签: c# thread-safety tcplistener

我需要编写一些使用TcpListener的代码。使用TcpListener的对象有3种可能:Listen,Stop Listen,Send message。这就是我的代码的样子:

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)。

另外,我不知道如果我想在不停止服务器侦听器状态的情况下向客户端发送一些消息(在某​​些单独的方法中),我知道如何保持此线程安全。

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

我建议等待事件而不是等待变量。在您当前的方案中,考虑您的循环测试是否为侦听器变量为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.
    }
}

发送不会影响上面的循环,只要它不响应上面的连接请求。

答案 1 :(得分:2)

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

要回答您的问题,您的问题是AcceptTcpClient是阻止通话。您将需要使用以BeginXXXEndXXX开头的APM(异步编程模型)方法,如MSDN BeginAcceptTcpClient

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