Windows - 同时等待事件和套接字

时间:2017-01-19 13:31:55

标签: c windows sockets winapi ipc

我正在编写需要等待新TCP连接的Win32-API C代码,而另一方面可以由任何其他进程/线程关闭。

因此,我需要以某种方式在停止事件上使用WaitForSingleObject并等待使用WSAAccept同时进行连接。

我在套接字和句柄上都尝试了WaitForMultipleObjects,但是新连接不会触发该函数(在新连接上也不会触发套接字上的WaitForSingleObject)。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您需要使用WSAWaitForMultipleEvents。对于套接字,这里有一些伪代码:

HANDLE hEvent[1];
hEvent[0] = WSACreateEvent();
WSAEventSelect(hSocket, hEvent[0], FD_READ | FD_WRITE);

while (WSAWaitForMultipleEvents(...)) {
    if (WSAEnumNetworkEvents(...)) { // Multiple events max exist
        if (... & FD_ACCEPT) {
        }
        if (... & FD_WRITE) {
        }
        ....
    }
}

如果您使用多个事件(例如停止事件来指示线程停止),请使用WSAWaitForMultipleEvents中的返回值来确定发出信号的事件(就像使用WaitForMultipleObjects一样)。

答案 1 :(得分:1)

你不能直接等待套接字句柄。

WSAAccept()是同步的,中止它的唯一方法是关闭侦听套接字。

对于您尝试执行的操作,请改用AcceptEx(),这是异步的,并支持重叠I / O和I / O完成端口。

如果使用Overlapped I / O,则可以将标准Win32事件对象与每个支持Overlapped I / O的套接字操作(AcceptEx()WSARecv()WSASend()等)相关联,并为您的停止事件使用标准的Win32事件对象。然后,您可以使用WaitForMultipleObjects()循环来了解哪些事件已发出信号并采取相应措施。

如果使用I / O完成端口,则根本不需要事件对象。您可以将每个套接字与单个IOCP队列相关联,并且每当支持IOCP的套接字操作完成时,将通知您的IOCP处理程序(调用GetQueuedCompletionStatus()或回调函数)。然后,您可以使用PostQueuedCompletionStatus()将自定义停止消息发布到IOCP队列。您的IOCP处理程序可以根据它接收的事件类型采取相应的行动。