如何使用WSASend()和IOCP模拟阻塞send()

How to simulate a blocking send() using WSASend() and IOCP?

本文关键字:send 模拟 何使用 WSASend IOCP      更新时间:2023-10-16

编辑: 这个问题没有必要,因为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);
        }
    }
}

为什么要这样做?

你认为它实现了什么?

来自WSASend 的MSDN文档

对于具有重叠属性的套接字,WSASend使用重叠I/O除非lpOverlapped和lpCompletionRoutine参数都为NULL。在这种情况下,套接字被视为非重叠套接字。

因此,只要不提供完成例程或OVERLAPPED结构,调用就会变成"非重叠"调用。这就是你想要的,一个阻塞直到数据被复制到网络堆栈的发送缓冲区的调用。。。

此外,我希望有问题的代码不要使用IOCP,因为如果是的话,它会崩溃得很厉害,也许不是现在,但最终会崩溃。你有比赛条件。如果使用IOCP,则OVERLAPPED结构必须存在,直到完成之后,并由调用GetQueuedCompletionStatus()的线程处理。您可以通过这种方式使用重叠I/O,只是不要将套接字与IOCP关联。您等待事件发出信号的事实并不意味着您在GetQueuedCompletionStatus()上阻塞的某个线程将检索完成并处理它,并在等待事件的调用完成且该函数返回之前完成对堆栈上创建的OVERLAPPED结构的触摸。