编辑:
这个问题不是必需的,因为 WSASend()
函数本质上可以在阻塞模式下使用,即使套接字具有重叠属性并且与完成端口相关联。要在阻塞模式下使用它:在调用 WSASend()
时不要提供重叠结构或完成例程。
我想确保当我发送数据时,函数只会在数据被放入发送缓冲区后返回。这就是我想出的(伪代码):
void WSASend_Block(char *arr, int length)
{
OVERLAPPED overlapped;
overlapped.hEvent = someEvent;
int result = WSASend(arr, length, &overlapped);
while(true)
{
if (result == 0) // IO operation has been scheduled
{
wait(overlapped.hEvent, INFINITE); // block until data is placed into send buffer
break;
}
else
{
result = WSASend(arr, length, &overlapped);
}
}
}
最佳答案
为什么要这样做?
您认为它实现了什么?
来自MSDN documentation对于 WSASend
For sockets with the overlapped attribute, WSASend uses overlapped I/O unless both the lpOverlapped and lpCompletionRoutine parameters are NULL. In that case, the socket is treated as a non-overlapped socket.
因此,只要不提供完成例程或 OVERLAPPED
结构,调用就会变成“非重叠”调用。这就是您想要的,一个阻塞调用,直到数据被复制到网络堆栈的发送缓冲区中...
此外,我希望有问题的代码没有使用 IOCP,因为如果使用 IOCP,它会严重崩溃,也许现在不会,但最终会崩溃。你有一个竞争条件。如果您使用 IOCP,则 OVERLAPPED
结构必须存在,直到完成发生并由调用 GetQueuedCompletionStatus()
的线程处理。您可以通过这种方式使用重叠 I/O,只是不要将套接字与 IOCP 相关联。您等待事件发出信号的事实并不意味着您在 GetQueuedCompletionStatus()
上阻塞的线程之一将检索完成并处理它并完成触摸 OVERLAPPED
在等待事件的调用完成并且该函数返回之前在堆栈上创建的结构。
关于c++ - 如何使用 WSASend() 和 IOCP 模拟阻塞 send()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28706644/