我有一个WinSock mySocket
,它在这样的循环中接收:
while(keepGoing){
FD_SET fsd;
FD_ZERO(&fds);
FD_SET(mySocket, &fds);
int result = select(1+mySocket, &fds, (fd_set *)0, (fd_set *)0, &timeout);
if(result>0 && FD_ISSET(mySocket, &fds){
result = recvfrom(mySocket, buff, NUM_BYTES, (struct sockaddr *)&add, &length);
// do stuff
}
}
如果我想停止接收,我可以将keepGoing
设置为false,但套接字可能仍在等待timeout
,然后才发现keepGoing
已更改。
假设我们不想更改超时值,有没有一种可靠的方法可以告诉套接字停止接收而不等待超时发生?
当errno
为EINTR
时,可以发出良性信号并检查keepGoing
标志。或者,您可以创建一个pipe
并将读取端添加到您的select
集合中。设置keepGoing
标志后关闭写入端。
int quitfds[2];
pipe(quitfds);
//...
FD_SET(quitfds[0], &fds);
//...
if (FD_ISSET(quitfds[0], &fds)) {
close(quitfds[0]);
continue;
}
编辑:Adam指出我在问题中遗漏了Winsock
参考资料。您可以使用socketpair
而不是pipe
。它似乎没有在Windows上实现,但我在这里找到了一个变通方法。Ben指出WSAEventSelect
允许混合不同的事件对象。感谢二者。