【问题标题】:Should i pass unique OVERLAPPED structure for each WSASend call , in this case?在这种情况下,我应该为每个 WSASend 调用传递唯一的 OVERLAPPED 结构吗?
【发布时间】:2017-08-06 21:17:17
【问题描述】:

我有一个套接字列表。(打开的连接)

我有 n 个工作线程。

线程循环:

while (1)
    {
        _this.result = GetQueuedCompletionStatus(a_server.server_iocp, &_this.numberOfBytesTransfered,
            &_this.completionKey, (OVERLAPPED**)&_this.iocp_task, INFINITE);
  ...
}

我有这个简单的结构:

struct iocp_send_global :public iocp_task<IOCP_SEND_GLOBAL> {
  OVERLLAPED ov; //overlapped struct at top
  std::atomic_uint32_t ref;

bool decr_ref(){ return ref.fetch_sub(1, std::memory_order_acq_rel) == 1;}


//packet data here
}

...

这是“广播”功能:

iocp_send_global * packet = new iocp_send_global;

[set packet data here]

for(int i=0;i<connectionsCount;++i){
    WSASend(connections[i],...,&packet,...); //posting same packet to all connections
}

我想在 GetQueuedCompletionStatus 调用返回重叠结果后在工作循环中执行此操作;

    if (_this.iocp_task->type == IOCP_SEND_GLOBAL) {
                    auto* task = (iocp_send_global*)_this.iocp_task;

                    if (!task->decr_ref()) {
                        _this.iocp_task = nullptr;
                        //dont delete the task yet, 
                        //all send post must finish first 
                        //[all posts share the same buffer]
                    }
                    else {
                    //delete the task containing the send data after all send posts finished
                       delete _this.iocp_task;
                       _this.iocp_task = nullptr;
                    }

}

根据我在 Microsoft WSASend 文档中阅读的内容,每个 WSASend 重叠调用都传递了自己的 OVERLAPPED 结构,但是当我 WSASend 相同的缓冲区时这是否有效?

谢谢!

【问题讨论】:

  • 只有当您不关心返回状态和 numberOfBytesTransfered(并且确切地知道哪个套接字 io 完成)时,您才能在多个请求中使用相同的 OVERLAPPED 缓冲区)。如果在这个结构上正确实现 addref/release 逻辑
  • 老兄,谢谢,我不在乎这些东西。只有它的 decr_ref,当我发布发送时,我将 ref 设置为 no。连接数
  • 请将其发布为 Answare,以便我接受!
  • 您需要清楚了解OVERLAPPED 的用途。这是IO_STATUS_BLOCK 的存储空间,其中存储了操作结果和附加信息(通常是 numberOfBytesTransfered)。如果在多个 IO 请求中使用相同的 OVERLAPPED - 此信息将未定义(多次覆盖)。所以通常它必须是每个操作唯一的。它还允许指向附加信息的指针(比如指向套接字)但是如果你不关心并且不需要所有这些 - 可以使用正式的和相同的 OVERLAPPED - 最低要求 - 内存桅杆在最后一次操作完成之前一直有效
  • 并且在您的代码中不可见您如何在WSASend 之前增加(addref)对结构的引用而不检查它的结果。

标签: c++ winapi


【解决方案1】:

您必须为每个调用传递不同的OVERLAPPED 缓冲区,因为您将进行多个挂起的调用。这在OVERLAPPED 结构的文档中有明确说明。

【讨论】:

    猜你喜欢
    • 2011-01-17
    • 2022-07-22
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2010-09-05
    相关资源
    最近更新 更多