如何在Windows中退出阻止recv()?
我有一个线程,它包含一个blocking如何在Windows中退出阻止recv()?,c,multithreading,sockets,winapi,winsock,C,Multithreading,Sockets,Winapi,Winsock,我有一个线程,它包含一个blockingrecv()调用,类似这样: { while(1) { recv(socket, buffer, sizeof(buffer), 0); } } 现在我要做的是从另一个线程向recv()函数发送信号,使其退出阻塞状态。我已经从另一个关于如何在Unix()中执行此操作的问题中阅读了以下答案: 要么: 使用setsockopt()和SO\u RCVTIMEO设置读取超时,每当它触发时,检查状态变量以
recv()
调用,类似这样:
{
while(1)
{
recv(socket, buffer, sizeof(buffer), 0);
}
}
现在我要做的是从另一个线程向recv()
函数发送信号,使其退出阻塞状态。我已经从另一个关于如何在Unix()中执行此操作的问题中阅读了以下答案:
要么:
setsockopt()
和SO\u RCVTIMEO
设置读取超时,每当它触发时,检查状态变量以查看是否已告知
让你自己停止阅读shutdown(sd,shuth\u RD)
将其关闭以进行输入。这将导致recv()
返回
从现在开始零select()
来告诉您何时读取,使用与
如上(1)所述的状态变量。然而,非阻塞模式引入了
send手术相当复杂,所以你应该
优先选择(1)或(2)以上recv()
?只有在以下情况下,阻塞recv()
才会退出:
recv()
,直到您知道有东西等待读取,如select()
、WSAAsyncSelect()
或WSAEventSelect()
所述
否则,请将套接字逻辑重新写入:
WSARecv()
或RIOReceive/Ex()
与重叠I/O或I/O完成端口一起使用。可以使用CancelIo/Ex()
取消I/O操作recv()
仅在以下情况下存在:
recv()
,直到您知道有东西等待读取,如select()
、WSAAsyncSelect()
或WSAEventSelect()
所述
否则,请将套接字逻辑重新写入:
WSARecv()
或RIOReceive/Ex()
与重叠I/O或I/O完成端口一起使用。可以使用CancelIo/Ex()
取消I/O操作选项#3是最常使用的选项,也是最便于携带的选项。我不知道那些神秘的“相当复杂”是什么。它是相当切割和干燥的。使用
选择时,不需要将插座设置为非阻塞模式。只需使用选择
,并短暂超时(比如200秒)。当select
返回时,检查状态变量以查看是否应该停止。只有在套接字有数据的情况下才调用recv
。如果你不想让它阻塞,那么使用阻塞函数是毫无意义的…@Olaf我确实想让它阻塞,我只想让它退出阻塞状态,这样我就可以在关闭应用程序时终止线程。@Trevor:那么你显然不想让它阻塞!或者你在图书馆里看到一些神奇的“解锁”电话?这些库只提供基本功能是有原因的。这就是为什么它们被称为“低级”库。您仍然没有解释select
等的实际问题是什么(在Linux上,您可以使用poll
/epoll
,但Windows总是不那么现代。选项#3是最常使用的选项,也是最可移植的选项。我不知道那些神秘的“相当复杂”是什么是的。它非常干燥。使用select
时,您不需要将插座设置为非阻塞模式。只需使用select
并短暂超时(比如200秒)。当select
返回时,检查状态变量以查看是否应该停止。仅在套接字有数据时调用recv
。如果不想阻止,则使用阻止函数是毫无意义的…@Olaf我确实想阻止它,我只想让它退出其阻止状态,以便终止t关闭我的应用程序时,请执行线程。@Trevor:那么你显然不希望它被阻止!或者你在库中看到了一些神奇的“取消阻止”调用吗?这些库只提供基本功能是有原因的。这就是为什么它们被称为“低级”的原因库。您仍然没有解释select
等的实际问题是什么(在Linux上,您可以使用poll
/epoll
,但Windows总是不那么现代。不会取消SynchronousIO()工作?@HarryJohnston我不知道。我没有试过,也没有记录它是否与套接字API一起工作。是否取消SynchronousIO()工作?@HarryJohnston我不知道。我没有试过,也没有记录它是否与套接字API一起工作。