1

我正在努力将一些相对简单的网络代码从 unix 移植到 Windows。

简而言之,有一个管理所有网络流量的网络线程。这个单线程poll()大部分时间都位于内部(我已经将其转换为select(), 在 Windows 上),网络线程仅在有传入网络数据时才唤醒。当客户端命令到达时,网络线程将命令触发到工作线程以实际在后端执行工作,然后返回侦听更多传入命令。命令是异步的——多个命令可以在一个套接字上输入,一个接一个接一个。在任何时候,单个连接上都可能有数十个未完成的命令,所有命令都在不同的工作线程中处理。

问题在于,当工作线程想要发送响应数据时,网络线程可能poll()在工作线程试图发送其结果时在内部处于休眠状态。网络线程必须等待poll()超时(或接收到另一个数据包)才能注意到有新的出站数据排队等待发送。

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

感谢您的任何建议!

4

2 回答 2

1

只有两种可能性,并且都不需要您提出的解决方案:

1) 您已经尝试在此连接上发送数据并且操作系统的发送队列已满。在这种情况下,不需要中止selector poll。无论如何,你现在不能在连接上写,你会尽快退出selectpoll自动退出。

2) 您当前没有尝试在此连接上发送数据。在这种情况下,也不需要中止selector poll。现在只需在工作线程中写入数据。(socket是非阻塞的吧select称呼)。

你真的不应该select在 Windows 上使用。这是一个可憎的行为,仅作为兼容性的粗略黑客提供。如果您计划“真正”支持 Windows,则不应将其设为二等舱。网络 I/O 确实必须是特定于平台的。

于 2012-11-01T05:27:55.207 回答
0

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

于 2012-11-04T05:04:29.320 回答