繁体   English   中英

多线程+socket应用的正确实现

[英]Proper implementation of multi-threaded + socket application

我有一个服务器和一个客户端应用程序,下面是它当前的实现方式: 服务器有一个循环,在它自己的线程中,它通过 TcpListener 侦听新连接。 如果有人连接,它会将 TcpClient 传递给一个循环,该循环专门监听该 TcpClient,并通过 NetworkStream 处理与该用户的所有交互。

在客户端,我有一个连接到服务器的 TcpClient。 我的理解是我需要将它分支到另一个线程,因为任何 IO 都会将其置于阻塞模式,我不能让它停止主线程。

到目前为止,我理解正确吗? 有没有更简单的方法来确保异步通信而不停止任一程序的主线程?

无论哪种方式,对于我的主要问题:如何确保正确处理所有这些线程和 sockets? 如果程序在仍处于阻塞模式时退出,它似乎会冻结。 那么如何中止套接字上的所有 IO 并告诉子线程中的无限循环我们已经完成了?

顺便说一句,这也是一个 Unity3d 项目,以防万一发生任何变化。

将每个新连接移交给自己的线程可能会限制您的可扩展性。 此外,没有理由要求客户端中的 I/O 进行线程切换。

您可以使用异步 I/O 解决这两个问题。 客户端上的BeginConnect/EndConnect ,服务器端的BeginRead/EndRead, BeginWrite/EndWrite用于读写。

然后一切都可以由事件驱动,而无需您自己的新线程。 连接完成会触发第一次异步读取,然后每个读取完成都会在该套接字上发布一个新的异步读取调用 - 无论如何,写入总是从您的 POV 确定的。

关闭 sockets 将导致挂起的读/写退出并出现错误,然后您应该能够干净地退出该过程。 请注意实施适当的锁定(可能只需要lock() )以确保 sockets 在关闭后不会在任何地方使用。

您应该有两个单独的线程,一个用于TcpListener ,另一个用于TcpClient ,它们自己运行。 初始化新线程时,将其IsBackground属性设置为 true,这样如果应用程序终止,它也会终止。

Thread listenerThread = new Thread(ListenerLoop);
listenerThread.IsBackground = true;
listernerThread.Start();

如果您使用 4.0 或ThreadPool.QueueUserWorkItem而不是线程,则可以使用Task

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM