【问题标题】:Winsock asynchronous multiple WSASend with one single bufferWinsock 异步多个 WSASend 与一个单个缓冲区
【发布时间】:2015-05-17 03:08:42
【问题描述】:

MSDN 声明“对于 Winsock 应用程序,一旦调用 WSASend 函数,系统就拥有这些缓冲区,应用程序可能无法访问它们。”

在服务器应用程序中,这是否意味着如果我想向多个客户端广播一条消息,我不能使用单个缓冲区来保存数据并使用该缓冲区在每个套接字上调用 WSASend?

【问题讨论】:

  • @Remy:我认为不是重复的;这个问题专门关于使用单个只读缓冲区进行多个相同的写入操作,而另一个问题中的 OP 想要解除分配或重用(即写入)缓冲区。假设对多个相同的写入使用只读缓冲区可能是一种特殊情况并非没有道理(尽管我怀疑答案不是)。
  • @HarryJohnston:这个 OP 的问题中没有任何内容表明正在发送的缓冲区是只读的。但应该非常清楚和明显的是,如果多个 WSASend() 操作同时从同一个缓冲区读取,那么在 all之前不得以任何原因(释放、覆盖等)触及该缓冲区> 待处理的WSASend() 操作已完成,就像文档(和其他答案)所建议的那样。重叠的 I/O,无论是用于套接字还是文件或其他什么,都不会将传出数据复制到内部缓冲区,而是从原始缓冲区读取,直到 I/O 完成。
  • @RemyLebeau:我相信问题是多个 WSASend() 操作是否可以同时从同一个缓冲区读取。在同一个缓冲区上再次调用 WSASend() 是否算作“访问”该缓冲区?
  • @HarryJohnston:这就是我的意思。对我来说,“访问”的东西听起来有点模棱两可。

标签: asynchronous buffer winsock send iocp


【解决方案1】:

我没有确认这是可能的文档参考,但我已经这样做了多年,并且还没有失败,YMMV。

只要每次发送具有唯一的OVERLAPPED 结构,您就可以使用单个数据缓冲区。由于WSABUF 数组被WSASend() 调用复制并且可以基于堆栈,我希望您可以拥有一个WSABUF 数组,但我从未这样做过。

您需要确保在所有数据写入完成之前保持该单个数据缓冲区“活动”。

如果您倾向于构建扩展的OVERLAPPED 使其包含数据缓冲区,这样的广播可能会使设计复杂化,但它确实避免了内存分配和内存复制。

注意:我有一个系统,我的扩展OVERLAPPED 结构包括数据缓冲区和operation code,它们是引用计数和池,用于发送和接收。在广播缓冲区时,我每次发送都使用一个单独的“缓冲区句柄”,这个句柄只是一个以不同方式扩展的OVERLAPPED 结构,它保存对原始数据缓冲区的引用并有自己的引用计数。当所有广播发送完成后,所有缓冲区句柄将被释放,而这些句柄又将释放底层数据缓冲区以供重用。

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-25
    • 1970-01-01
    相关资源
    最近更新 更多