一个 IOCP 文档解释问题 - 缓冲区所有权歧义 [英] An IOCP documentation interpretation question - buffer ownership ambiguity

查看:31
本文介绍了一个 IOCP 文档解释问题 - 缓冲区所有权歧义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因为我的母语不是英语,所以我可能会遗漏一些东西,所以也许这里有人比我更了解.

Since I'm not a native English speaker I might be missing something so maybe someone here knows better than me.

取自 WSASendMSDN 上的注释:

Taken from WSASend's doumentation at MSDN:

lpBuffers [in]

lpBuffers [in]

指向 WSABUF 数组的指针结构.每个 WSABUF 结构包含一个指向缓冲区的指针和缓冲区的长度,以字节为单位.为一个Winsock 应用程序,一旦 WSASend函数被调用,系统拥有这些缓冲区和应用程序可能不访问它们.这个数组必须在有效期内保持有效发送操作.

A pointer to an array of WSABUF structures. Each WSABUF structure contains a pointer to a buffer and the length, in bytes, of the buffer. For a Winsock application, once the WSASend function is called, the system owns these buffers and the application may not access them. This array must remain valid for the duration of the send operation.

好的,你能看到粗体吗?那是不清楚的地方!

Ok, can you see the bold text? That's the unclear spot!

我能想到这行的两个翻译(可能是别的东西,你说出来的):
翻译 1 - "buffers" 指的是我在调用此函数时传递的 OVERLAPPED 结构.只有在收到有关它的完成通知时,我才能再次重用该对象.
翻译 2 - 缓冲区"指的是实际缓冲区,即包含我要发送的数据的缓冲区.如果 WSABUF 对象指向一个缓冲区,那么在操作完成之前我不能触摸这个缓冲区.

I can think of two translations for this line (might be something else, you name it):
Translation 1 - "buffers" refers to the OVERLAPPED structure that I pass this function when calling it. I may reuse the object again only when getting a completion notification about it.
Translation 2 - "buffers" refer to the actual buffers, those with the data I'm sending. If the WSABUF object points to one buffer, then I cannot touch this buffer until the operation is complete.

谁能说出对那句话的正确解释是什么?

Can anyone tell what's the right interpretation to that line?

而且..... 如果答案是第二个 - 你会如何解决?
因为对我来说这意味着对于我发送的每个数据/缓冲区,我必须在发送方保留它的副本 - 因此在高流量应用程序上有许多待处理"缓冲区(不同大小),这真的会发生损害可扩展性".

And..... If the answer is the second one - how would you resolve it?
Because to me it implies that for each and every data/buffer I'm sending I must retain a copy of it at the sender side - thus having MANY "pending" buffers (in different sizes) on an high traffic application, which really going to hurt "scalability".

声明 1:
除了上面的段落(和...."),我认为 IOCP 将要发送的数据复制到它自己的缓冲区并从那里发送,除非您设置 SO_SNDBUF 为零.

声明 2:
我使用堆栈分配的缓冲区(你知道,在函数体中类似于 char cBuff[1024]; - 如果主要问题的转换是第二个选项(即缓冲区必须保持原样,直到发送完成),然后……真的把事情搞砸了!你能想出解决方法吗?(我知道,我在上面问过).

Statement 2:
I use stack-allocated buffers (you know, something like char cBuff[1024]; at the function body - if the translation to the main question is the second option (i.e buffers must stay as they are until the send is complete), then... that really screws things up big-time! Can you think of a way to resolve it? (I know, I asked it in other words above).

推荐答案

答案是重叠结构和数据缓冲区本身不能被重用或释放,直到操作完成.

The answer is that the overlapped structure and the data buffer itself cannot be reused or released until the completion for the operation occurs.

这是因为操作是异步完成的,所以即使数据最终被复制到 TCP/IP 堆栈中操作系统拥有的缓冲区中,这可能直到将来的某个时间才会发生,并且您会收到写入通知的时间完成发生.请注意,如果您在没有显式流量控制的情况下发送并依靠 TCP 堆栈为您进行流量控制,则写入完成可能会延迟相当长的时间(请参阅此处:一些使用 WSASend 的 OVERLAPS 没有使用 GetQueuedCompletionStatus 及时返回?) ...

This is because the operation is completed asynchronously so even if the data is eventually copied into operating system owned buffers in the TCP/IP stack that may not occur until some time in the future and you're notified of when by the write completion occurring. Note that with write completions these may be delayed for a surprising amount of time if you're sending without explicit flow control and relying on the the TCP stack to do flow control for you (see here: some OVERLAPS using WSASend not returning in a timely manner using GetQueuedCompletionStatus?) ...

你不能使用堆栈分配的缓冲区,除非你在重叠结构中放置一个事件并阻塞它直到异步操作完成;这样做没有什么意义,因为您增加了普通阻塞调用的复杂性,并且通过发出异步调用然后等待它并没有获得太多好处.

You can't use stack allocated buffers unless you place an event in the overlapped structure and block on it until the async operation completes; there's not a lot of point in doing that as you add complexity over a normal blocking call and you don't gain a great deal by issuing the call async and then waiting on it.

在我的 IOCP 服务器框架中(您可以从 此处) 我使用动态分配的缓冲区,其中包括 OVERLAPPED 结构和引用计数.这意味着清理(在我的情况下,它们被返回到池中以供重用)在完成发生并释放引用时发生.这也意味着您可以选择在操作后继续使用缓冲区,清理仍然很简单.

In my IOCP server framework (which you can get for free from here) I use dynamically allocated buffers which include the OVERLAPPED structure and which are reference counted. This means that the cleanup (in my case they're returned to a pool for reuse) happens when the completion occurs and the reference is released. It also means that you can choose to continue to use the buffer after the operation and the cleanup is still simple.

另见此处:I/O 完成端口,如何释放 Per Socket Context 和 Per I/O Context?

这篇关于一个 IOCP 文档解释问题 - 缓冲区所有权歧义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆