我有一个服务器和一个客户端应用程序,这是当前的实现方式:服务器在其自己的线程中有一个循环,该循环通过TcpListener监听新的连接。如果有人连接,它将TcpClient传递到一个循环,该循环专门监听该TcpClient,并通过NetworkStream处理与该用户的所有交互。
在客户端上,我有一个TcpClient连接到服务器。据我了解,我需要将其分支到另一个线程,因为任何IO都会将其置于阻塞模式,并且我不能让它停止主线程。
到目前为止,我是否正确理解?有没有更简单的方法来确保异步通信而又不停止两个程序的主线程?
无论哪种方式,对于我的主要问题:如何确保所有这些线程和套接字都得到正确处理?如果程序在仍处于阻止模式时退出,则似乎冻结了。那么,如何中止套接字上的所有IO,并告诉子线程无限循环我们已经完成了呢?
顺便说一下,这也是一个Unity3d项目,以防万一。
最佳答案
将每个新连接移交给其自己的线程可能会限制您的可扩展性。同样也没有理由要求客户端中的I/O进行线程切换。
您可以使用异步I/O解决这两个问题。客户端上的BeginConnect/EndConnect
,服务器端上的BeginRead/EndRead, BeginWrite/EndWrite
用于读写。
这样,一切都可以由事件驱动,而无需您自己的新线程。连接完成会首先触发异步读取,然后每个读取完成都会在该套接字上发布一个新的异步读取调用-无论如何,写入始终是从POV确定的。
关闭套接字将导致挂起的读/写操作退出并出现错误,然后您应该可以完全退出该过程。请注意,您必须实现适当的锁定(可能只需要lock()
),以确保套接字关闭后在任何地方都不会使用。
关于c# - 正确实现多线程+套接字应用程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6643058/