有多少异步接口的请求能够在同一个插座怎么回事? [英] how many async socket requests can be going on on the same socket?

查看:124
本文介绍了有多少异步接口的请求能够在同一个插座怎么回事?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我打电话BeginSend套接字上的,我通过一个将被调用(由不同的线程),当数据已发送委托。

When I call BeginSend on a socket, I pass a delegate which will be called (by a different thread) when the data has been sent.

会发生什么,如果我叫BeginSend还有一次,而第一个尚未回呼?

What would happen if I call BeginSend another time while the first has not yet been 'callbacked'?

什么是数据发送正确的行为?做BeginSend,并在回调做EndSend并启动另一个发送?或者,它实际上是明智的,有多个BeginSends在同一时间工作?

What is the correct behavior to send data? do BeginSend, and on the callback do EndSend and start another send? Or is it actually wise to have multiple BeginSends working at the same time?

这是MSDN上的BeginSend网页,其中并没有这个问题给出一个答案: BeginSend MSDN

this is the BeginSend page on MSDN which doesn't give an answer to this question: BeginSend msdn

推荐答案

作为最高统帅部说,多个挂起 BeginSend 通话将正常工作。你也许需要记住,虽然有些事情承担。

As O.K.W. says, multiple pending BeginSend calls will work fine. You probably DO need to bear in mind some things though.

首先,如果这是一个TCP套接字那么这仍然是来自对等数据的单个流。

Firstly if this is a TCP socket then this is still a single stream of data from peer to peer.

其次,如果发生在同一个线程所有的 BeginSend 调用,那么结果将是对等接收呼叫的顺序数据。如果从不同的线程会出现你的 BeginSend 调用,那么数据可以到达任何顺序有可能会每个发送之间的竞争条件。这可能会或可能不会向你(取决于如果您将离散的,完整的信息,每个发送或没有)。

Secondly if all your BeginSend calls occur on the same thread then the result will be that the peer receives the data in the order of the calls. If your BeginSend calls occur from different threads then the data could arrive in any order as there will likely be a race condition between each of the sends. This may or may not matter to you (depends if you're sending discrete, complete messages with each send or not).

第三,如果你使用的是TCP和发送超过code。在插座的另一端就可以收到你可以填充TCP窗口和TCP协议栈将开始对数据流进行流量控制得更快。如果继续发行 BeginSend 调用,那么你最终可能会在一个情况下你的回调需要更长的时间和更长的时间才能被称为对您的服务器排队的TCP协议栈的数据发送(你只能得到回调,一旦数据被发送和TCP窗口的流量控制将是preventing新的数据被发送到TCP窗口不再是'全',即对已发送的ACK的一些数据这是在飞行)。

Thirdly if you are using TCP and sending faster than the code at the other end of the socket can receive then you may fill the TCP Window and the TCP stacks will start to perform flow control on your data stream. If you continue to issue BeginSend calls then you MAY end up in a situation where your callbacks take longer and longer to be called as the TCP stack on your server queues data to send (you only get the callback once the data has been sent and the TCP Window based flow control will be preventing new data being sent until the TCP Window is no longer 'full'; i.e. the peer has sent ACKs for some of the data that is in flight).

然后就可以进入一个情况,即你正在使用的资源发送机器上的不可控的方式(您发出 BeginSend ,而且不知道什么时候会完成每发送使用内存缓冲区发送和潜在非分页池倒在Winsock的code ... 非分页池是一个系统范围的资源是相当稀缺的pre Vista的操作系统和一些顽劣驾驶者可以蓝屏框,如果非分页池不足或已耗尽。什么是内存越多,你也可以锁定页到内存中,有对锁定内存页的数量另一个系统级限制。

You can then get into a situation whereby you are using up resources on the sending machine in an uncontrollable manner (you issue a BeginSend and have no idea when it will complete and each send uses memory for the buffer being sent and potentially non-paged pool down in the Winsock code... Non-paged pool is a system wide resource and is quite a scarce on pre Vista OSs and some badly behaved drivers can blue screen the box if non-paged pool is low or exhausted. What's more you may also be locking pages of memory into memory and there's another system wide limit on the number of locked memory pages.

这些问题通常最好实现自己的协议级流量控制,限制了 BeginSend 通话可以挂起在任一时刻的数字,因为(使用协议级别ACK,也许),或与TCP窗口的流量控制,并使用完成挂起发送发出新的发送,你可以排队要发送的数据在您自己的内存,并可以完全控制所用的资源和你做了什么如果你排队太多的数据。看到这里我的博客文章以获取更多的细节:<一href="http://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and-asynchronous-writes.html">http://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and-asynchronous-writes.html

Because of these issues it's usually best to implement your own protocol level flow control which limits the number of BeginSend calls that can be pending at any one time (using a protocol level ACK, perhaps) or to work with the TCP Window flow control and use the completion of a pending send to issue a new send and you can queue data to send in your own memory and have complete control over the resources used and what you do if you queue "too much" data. See my blog post here for more detail on this: http://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and-asynchronous-writes.html

请参阅该答复:<一href="http://stackoverflow.com/questions/1997691/what-happens-when-tcp-udp-server-is-publishing-faster-than-client-is-consuming/1998127#1998127">what当TCP / UDP服务器发布比客户端快被消耗?用于在TCP窗口流量控制等信息时发生重叠的I / O(在C ++中的土地),当你忽视它,问题太多重叠的发送情况。 ..

See this reply: what happens when tcp/udp server is publishing faster than client is consuming? for more information on TCP Window flow control and what happens with overlapped I/O (in C++ land) when you ignore it and issue too many overlapped sends...

总之,发布多个并发 BeginSend 调用的方式来优化TCP数据流,但你需要确保你不发送太快,因为一旦你你消耗的资源中,你无法控制,这可能是致命的,你的code运行的计算机的方式。因此,不允许无限多个 BeginSend 要求是优秀的,理想的配置文件中,以确保你是不是排气系统范围内的资源。

In summary, posting multiple concurrent BeginSend calls is the way to optimum TCP data flow but you need to make sure you don't send "too fast" as once you do you are consuming resources in a manner which you can't control and which is potentially fatal for the machine on which your code is running. So don't allow an unbounded number of BeginSend calls to be outstanding and, ideally, profile the box to ensure that you are not exhausting system wide resources.

这篇关于有多少异步接口的请求能够在同一个插座怎么回事?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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