线程和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)时,我不确定如何确保线程的安全。
此外,当我想在不停止服务器侦听器状态的情况下向客户端发送一些消息(以某种分离的方法)时,我不确定如何确保这个线程的安全。
谢谢你的帮助。
我建议等待一个事件,而不是等待一个变量。在当前方案中,考虑循环测试侦听器变量是否为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
是一个阻塞呼叫。您将希望使用以BeginXXX
和EndXXX
开头的APM(异步编程模型)方法,如MSDN BeginAcceptTcpClient。
这些方法不会阻塞线程,但您必须处理并发性。