c++ - 如何使用 WSASend() 和 IOCP 模拟阻塞 send()?

标签 c++ sockets winapi network-programming iocp

编辑: 这个问题不是必需的,因为 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/

相关文章:

java - Socket 编程中的 ProgressMonitorInputStream

c - 尝试写入 struct ip 时出现错误 “dereferencing pointer to incomplete type”

c++ - MFC CComboBox::InitStorage 文档说明

c++ - 非局部非内联变量的初始化 : does it take place strictly before the `main()` function call?

sockets - 如何更改套接字的 IP_MULTICAST_IF

python - 使用 C++ 客户端通过 Zmq 发送 JSON 对象 - Python 服务器

delphi - 暂停/中断作为键盘快捷键(Win32,*可能*特定于 Delphi)

c++ - 当 hModule 和 lpProcName 有效时 GetProcAddress 返回 NULL

c++ - 如何仅使用标准库将 C++ 对象写入文件

c++ - 将函数绑定(bind)到范围以生成迭代函数