由于我不是母语为英语的人,我可能会遗漏一些东西,所以也许这里的人比我更清楚。
取自WSASend在MSDN上的推文:
lpBuffers [in]
指向WSABUF数组的指针 结构。每个WSABUF结构 包含指向缓冲区的指针和 缓冲区的长度(以字节为单位)。为一个 Winsock应用程序,曾经是WSASend 函数被调用,系统拥有 这些缓冲区和应用程序可能会 不能访问它们。这个数组必须 在有效期内保持有效 发送操作。
好的,你能看到粗体文字吗?那是不清楚的地方!
我可以想到这一行的两个翻译(可能是别的,你的名字):
翻译1 - “buffers”是指我在调用它时传递此函数的OVERLAPPED结构。只有在收到关于它的完成通知时,我才可以重新使用该对象
翻译2 - “缓冲区”指的是实际缓冲区,那些带有我正在发送的数据的缓冲区。如果WSABUF对象指向一个缓冲区,那么在操作完成之前我无法触摸此缓冲区。
任何人都能说出对该线的正确解释是什么吗?
并且.....如果答案是第二个 - 你将如何解决它? 因为对我而言,这意味着对于我发送的每个数据/缓冲区,我必须在发送方保留它的副本 - 因此在高流量应用程序上有很多“待定”缓冲区(不同大小),这真的很有用伤害“可扩展性”。
声明1:
除了上面的段落(“And ....”)之外,我认为IOCP将要发送的数据复制到它自己的缓冲区并从那里发送,除非你将SO_SNDBUF设置为零。 / p>
声明2:
我使用堆栈分配的缓冲区(你知道,在函数体上类似char cBuff[1024];
- 如果主要问题的转换是第二个选项(即缓冲区必须保持原样,直到发送完成),然后。 ......这真的搞砸了很多东西!你能想出解决问题的方法吗?(我知道,我上面用其他的方式问过它)。
答案 0 :(得分:3)
答案是重叠结构和数据缓冲区本身在操作完成之前不能重复使用或释放。
这是因为操作是异步完成的,所以即使数据最终被复制到TCP / IP堆栈中的操作系统拥有的缓冲区中,这些缓冲区可能在将来的某个时间内不会发生,并且通知您何时写入完成发生。请注意,对于写入完成,如果您在没有显式流量控制的情况下发送并依赖TCP堆栈为您执行流量控制,这些可能会延迟一段时间(请参阅此处:some OVERLAPS using WSASend not returning in a timely manner using GetQueuedCompletionStatus?)...
除非将事件放在重叠结构中并阻塞,否则不能使用堆栈分配的缓冲区,直到异步操作完成为止;这样做并没有太大的意义,因为你增加了普通阻塞调用的复杂性,并且你没有通过发出调用异步然后等待它来获得很多好处。
在我的IOCP服务器框架中(您可以从here免费获得)我使用动态分配的缓冲区,其中包括OVERLAPPED结构和引用计数。这意味着清理(在我的情况下,它们被返回到池中以供重用)在完成发生并且引用被释放时发生。这也意味着您可以选择在操作后继续使用缓冲区,并且清理仍然很简单。
另见:I/O Completion Port, How to free Per Socket Context and Per I/O Context?