Asynchronous Winsock异步多个WSASend和一个缓冲区

Asynchronous Winsock异步多个WSASend和一个缓冲区,asynchronous,buffer,winsock,send,iocp,Asynchronous,Buffer,Winsock,Send,Iocp,MSDN声明“对于Winsock应用程序,一旦调用WSASend函数,系统拥有这些缓冲区,应用程序可能无法访问它们。” 在服务器应用程序中,这是否意味着如果我想向多个客户端广播一条消息,我就不能使用一个缓冲区来保存数据并在每个套接字上使用该缓冲区调用WSASend?我没有文档参考来证实这一点,但我已经做了很多年,而且还没有失败,YMMV 您可以使用单个数据缓冲区,只要每次发送都有唯一的重叠结构。由于WSABUF数组是由WSASend()调用复制的,并且可以基于堆栈,因此我希望您可以有一个WSAB

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


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

我没有文档参考来证实这一点,但我已经做了很多年,而且还没有失败,YMMV

您可以使用单个数据缓冲区,只要每次发送都有唯一的
重叠
结构。由于
WSABUF
数组是由
WSASend()
调用复制的,并且可以基于堆栈,因此我希望您可以有一个
WSABUF
数组,但我从来没有这样做过

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

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


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

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