我正在编写需要等待新TCP连接的Win32-API C代码,而另一方面可以由任何其他进程/线程关闭。
因此,我需要以某种方式在停止事件上使用WaitForSingleObject并等待使用WSAAccept同时进行连接。
我在套接字和句柄上都尝试了WaitForMultipleObjects,但是新连接不会触发该函数(在新连接上也不会触发套接字上的WaitForSingleObject)。
有什么想法吗?
答案 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处理程序可以根据它接收的事件类型采取相应的行动。