如何使用 WSASend() 和 IOCP 模拟阻塞 send()?
How to simulate a blocking send() using WSASend() and IOCP?
编辑:
这个问题不是必需的,因为 WSASend()
函数本质上可以在阻塞模式下使用,即使套接字具有重叠属性并且与完成端口相关联。要在阻塞模式下使用它:调用 WSASend()
.
时不要提供重叠结构或完成例程
我想确保当我发送数据时,该函数仅在数据已放入发送缓冲区后才会 return。所以这就是我想出的(伪代码):
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
结构,调用就会变成 "non overlapped" 调用。这就是您想要的,一个阻塞调用,直到数据被复制到网络堆栈的发送缓冲区中...
此外,我希望有问题的代码没有使用 IOCP,因为如果使用 IOCP,它会严重崩溃,也许现在不会,但最终会崩溃。你有一个竞争条件。如果您正在使用 IOCP,那么 OVERLAPPED
结构必须存在,直到完成发生并由调用 GetQueuedCompletionStatus()
的线程处理。您可以通过这种方式使用重叠 I/O,只是不要将套接字与 IOCP 相关联。您等待事件发出信号这一事实并不意味着您在 GetQueuedCompletionStatus()
上阻塞的线程之一将检索完成并处理它并完成接触您在其上创建的 OVERLAPPED
结构调用等待事件完成之前的堆栈和该函数 returns。
编辑:
这个问题不是必需的,因为 WSASend()
函数本质上可以在阻塞模式下使用,即使套接字具有重叠属性并且与完成端口相关联。要在阻塞模式下使用它:调用 WSASend()
.
我想确保当我发送数据时,该函数仅在数据已放入发送缓冲区后才会 return。所以这就是我想出的(伪代码):
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
结构,调用就会变成 "non overlapped" 调用。这就是您想要的,一个阻塞调用,直到数据被复制到网络堆栈的发送缓冲区中...
此外,我希望有问题的代码没有使用 IOCP,因为如果使用 IOCP,它会严重崩溃,也许现在不会,但最终会崩溃。你有一个竞争条件。如果您正在使用 IOCP,那么 OVERLAPPED
结构必须存在,直到完成发生并由调用 GetQueuedCompletionStatus()
的线程处理。您可以通过这种方式使用重叠 I/O,只是不要将套接字与 IOCP 相关联。您等待事件发出信号这一事实并不意味着您在 GetQueuedCompletionStatus()
上阻塞的线程之一将检索完成并处理它并完成接触您在其上创建的 OVERLAPPED
结构调用等待事件完成之前的堆栈和该函数 returns。