【问题标题】:How to initialize WSAOVERLAPPED when using IOCP?使用 IOCP 时如何初始化 WSAOVERLAPPED?
【发布时间】:2015-03-05 00:10:57
【问题描述】:

我不确定在使用 IOCP 时如何初始化 WSAOVERLAPPED。我认为我根本不需要初始化它,我只将WSAOVERLAPPED.hEvent 设置为 NULL(也不确定这是否有必要)。这段代码是否正确:

// Send data
char buffer[1024];

WSABUF wsaBuf;
wsaBuf.buf = buffer;
wsaBuf.len = 1024;

WSAOVERLAPPED wsaOverlapped;
wsaOverlapped.hEvent = NULL;

WSASend(s, &wsaBuf, 1, NULL, 0, &wsaOverlapped, NULL);

另外,在使用WSARecv() 时初始化OVERLAPPED 是否与初始化WSAOVERLAPPED 相同?

【问题讨论】:

  • 您显示的代码已损坏。数据缓冲区和OVERLAPPED 必须都有效,直到重叠发送完成并从 IOCP 中提取完成。只有 WSABUF 可以基于堆栈并且仅在 WSASend() API 调用期间存在。
  • @Len Holgate 所以bufferwsaOverlapped 应该在堆上创建?
  • 是的。理想情况下,使用某种池分配器可以让您重用它们,而不是直接在堆上。

标签: c++ sockets winapi network-programming iocp


【解决方案1】:
   memset(&wsaOverlapped, 0, sizeof(wsaOverlapped));

或将所有值显式设置为零。

【讨论】:

    【解决方案2】:

    WSAOVERLAPPED 结构服从the same rules as the OVERLAPPED structure,即,

    在函数调用中使用该结构之前,该结构的任何未使用成员都应始终初始化为零。否则,函数可能会失败并返回 ERROR_INVALID_PARAMETER。

    【讨论】:

    • 但是我应该在将WSAOVERLAPPEDOVERLAPPED 的任何成员传递给WSASend()WSARecv() 之前初始化它们吗?
    • 当然。如果您正在使用它们,则必须将它们初始化为适当的值,例如,通过将 hEvent 设置为有效的事件句柄;如果您不使用它们,则必须将它们初始化为零。
    • 如果我不想使用事件,只想通过完成包得到通知,我应该将WSAOVERLAPPED.hEvent设置为NULL,还是完全不初始化也可以?还有,其他成员呢,是我用的还是系统用的?
    • @Remy Lebeau 我正在使用 IOCP,但同时我已将 WSAOVERLAPPED.hEvent 分配给一个有效的事件实例,并等待它。发生的事情是我能够成功等待WSASend() 完成,那么它怎么可能是用户定义的数据?我的意思是系统不会看到WSAOVERLAPPED.hEvent 不是NULL,所以将其视为有效的事件实例?
    • @user4592590:显然hEvent 的含义取决于WSASend()/WSARecv()lpCompletionRoutine 参数的值,而不取决于套接字是否与IOCP 关联。如果将lpCompletionRoutine 设置为NULL,则必须将hEvent 设置为有效的事件对象或NULL。如果不为 NULL,则 I/O 完成时会发出事件信号,IOCP 也会收到一个完成包。
    猜你喜欢
    • 2020-09-20
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2017-11-06
    相关资源
    最近更新 更多