编辑:
这个问题不是必需的,因为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);
}
}
}
答案 0 :(得分:4)
你为什么要这样做?
您认为它实现了什么?
来自WSASend
的{{3}}
对于具有重叠属性的套接字,WSASend使用重叠的I / O. 除非lpOverlapped和lpCompletionRoutine参数都是 空值。在这种情况下,套接字被视为非重叠套接字。
因此,根本不提供完成例程或OVERLAPPED
结构,并且呼叫将成为"非重叠"呼叫。这是你想要的,一个阻塞的呼叫,直到数据被复制到网络堆栈的发送缓冲区......
另外,我希望有问题的代码不会使用IOCP,因为它会崩溃,如果它可能不是现在,但最终会崩溃。你有竞争条件。如果您正在使用IOCP,则OVERLAPPED
结构必须存在,直到完成发生并由调用GetQueuedCompletionStatus()
的线程处理。您可以通过这种方式使用重叠I / O,只是不要将套接字与IOCP相关联。您等待事件发出信号的事实并不意味着您在GetQueuedCompletionStatus()
上阻塞的某个线程将检索完成并处理它并完成触及您在上创建的OVERLAPPED
结构在事件调用等待之前的堆栈完成并且该函数返回。