2012-11-01 95 views
1

我正在努力将一些相对简单的网络代码从unix移植到Windows。将多线程网络服务器从unix移植到windows

简而言之,有一个管理所有网络流量的网络线程。这个单线程大部分时间位于poll()之内(我已经将它转换为select(),在Windows上),网络线程只有在有传入的网络数据时才会唤醒。当客户端命令到达时,网络线程将该命令发送给工作线程,以便在后端实际执行工作,然后返回到侦听更多传入命令。命令是异步的 - 多个命令可以进入一个套接字,一个接一个接一个。在任何时候,在一个连接上可以有几十个优秀的命令,所有这些命令都在各种工作线程中工作。

问题是,当工作线程想要发送响应数据时,网络线程可能在工作线程尝试发送结果时在poll()内部睡着。网络线程必须等待poll()超时(或接收另一个数据包),才会发现有新的出站数据排队等待发送。

在unix下,我通过在poll()正在监视的描述符中包含一个管道来处理这个问题,并且当一个工作线程有出站数据要发送时,它还将一个字节的数据写入管道以唤醒网络线程。但是WinSock似乎只支持在套接字上等待,所以这种方法在Windows中不适用于我。有没有什么方法可以让我在Windows上使用WinSock抢救这个体系结构(这样我可以在不同平台之间共享大部分代码),还是别无选择,只能编写自定义网络服务器实现以用于Windows?

感谢您的咨询!

回答

1

只能有两种可能,也不需要你提出了解决方案:

1)您已经尝试发送此连接数据和OS的发送队列已满。在这种情况下,不需要中止selectpoll。无论如何,您现在无法在连接上写信,并且您将尽快自动退出selectpoll

2)您当前未尝试在此连接上发送数据。在这种情况下,也不需要中止selectpoll。现在只需在工作线程中写入数据。 (套接字是非阻塞的,对吧?)如果你不写所有的数据,那只会是因为操作系统的发送队列已满,在这种情况下通常不会急于写入(设置合理的超时select呼叫)。

你真的不应该在Windows上使用select。这只是一种可憎的行为,仅仅是为了兼容性。如果你打算“真正”支持Windows,那么你不应该把它变成二流的。网络I/O确实是平台特定的。

0

而不是在Windows上使用select,如果您使用IO完成端口和发布读取缓冲区,您将获得明显更好的结果。在IOCP模型下可以使用PostQueuedCompletionStatus API与服务于IOCP的线程进行通信。

+0

是的,绝对正确。但在这种情况下,我正在使用为BSD套接字编写的现有代码,并试图尽量减少我为Windows构建编写和维护的自定义代码的数量。如果性能实际上成为问题并且在这部分代码中进行性能分析,那么切换到IOCP是我列表中的第一件事。在此之前,我可能不打扰。 :) –