正确实现多线程+套接字应用程序

本文关键字:套接字 应用程序 多线程 实现 | 更新日期: 2023-09-27 18:01:36

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

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

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

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

顺便说一下,这也是一个Unity3d项目,以防改变任何东西

正确实现多线程+套接字应用程序

将每个新连接交给它自己的线程可能会限制您的可伸缩性。此外,没有理由要求客户机中的I/O线程切换。

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

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

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

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

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

你可以使用Task,如果你使用4.0或ThreadPool.QueueUserWorkItem代替线程。