好文档 - 专业文书写作范文服务资料分享网站

IOCP发送大数量的问题

天下 分享 时间: 加入收藏 我要投稿 点赞

1. IOCP发送大数量的问题

2. IOCP发送大数量的问题

有A,B两块数据,如AB两块数据,如果A数据比较大,异步只发送了一部分就返回了,B数据已经提交,这时候再发A剩下的部分就乱顺序了 ,该如何处理。

所有重叠操作可确保按照应用程序投递的顺序执行. 然而, 不能确保从完成端口返回的完成通知也按照上述顺序执行\由此可见, \操作的执行\和\操作结果的通知\这二者的顺序并不能保证完成一致. 在这种情况下, 在这种情况下, 为每个客户端单独作一个发送队列, 有利于进行发送控制. 对于同一个客户端而言, 前一次发送的结果没有返回之前, 针对于同一socket, 不再发后续数据.当WSASend的时候,你的应用需要把应用缓冲提交给 socket缓冲,然后系统会把socket缓冲提交给TCP缓冲。这就算是一次完成的WSASend过程。 当你的应用把应用缓冲提交给 socket缓冲成功后(注意,这个时候,应用缓冲并没有提交到TCP缓冲),这个时候,Get...就成功回收了(10M)。 你Get..回收成功了,并不代表你的所有的数据都发送出去了。可能他们都在TCP缓冲里(TCP缓冲也是有个最大值的,并不是提交任何大都可以,你可以尝试把10M提高继续测试下)。 IOCP是要么提交成功要么提交失败,所以不用考虑发送出去半个包的情况。如何知道实际发送的数据量,这个拍拍脑袋就能想到办法,

接收方收到发送方的包回一个确认包就可以了,发送方收到确认包以后就知道成功发送的数据量。在发送方, 如何知道已经发了多少数据量, 还是依靠GET函数的返回数比较准确. 这个数字, 本身也是来自于底层TCP通信时的协议操作结果.我的意思是制订一个通讯协议以后就可以拆包和组包, 因此在收到一个完整包以后就可以给发送方发包确认。

2. IOCP:GetQueuedCompletionStatus返回后,完成事件处理时间相当长。

感觉单独用线程处理请求要好一些,但是从我刚才性能分析来看 在通常情况下I/O线程和处理线程合并起来性能要好一些,同时处理耗时操作的线程比单独用来处理耗时操作的线程个数要多,所以性能当然要好一些。

但是,带来一个负面问题,本来我使用一个队列和一个线程来处理数据包,这样在游戏的逻辑部分不存在线程同步的问题。 如果将处理过程放进GET线程的话,就变成N多个线程处理数据包了,虽然在socket的读取这层性能提高了,但是当数据包到达逻辑层后, 还是需要频繁的加锁的阿~同样是有消耗的,甚至消耗会更大。

IOCP有多个get线程,这些线程互不相关,只负责处理socket上的读取,以及读取后针对不同的session进行拼包。 这个过程不需要做任何的同步锁定。 当拼包完成后,即获取到了一个完整的逻辑包时,将其插进处理队列,这里队列需要锁定一次。 然后,有一个单独的处理线程,从

队列中取逻辑包出来处理,这个线程即逻辑层的单线程。 这样做的好处是,尽量将没有逻辑意义的处理放进多个线程处理,将最后的结果(即需要逻辑处理的东西),交给单线程处理。 以最大限度的缩短单线程处理数据包的时间。 关于多线程还是单线程, 这个问题的争论由来已久. 总体而言, 我们需要在这两者之间作个权衡, 我比较赞同的观点是: 主逻辑线程只有一个, 如果主逻辑线程中存在耗时较长的逻辑, 则想办法分离, 分离的方法其中之一就是看这部分逻辑能否并行处理, 如果可以, 就在这里作\分阶段\的多线程. 主逻辑线程为多个时,带来的是调试和纠错等相关的时间开销. 这类服务器的业务逻

辑I/O负载比较大,根本无法单线程处理。在这种环境下开多个GET*** 就比通过队列单线程来处理业务逻辑要高效的多。

我认为调用Get***和处理在同一个线程也没关系,只要开个线程足够多,比如10个Thread。 比你开4个Get**线程,6个处理线程的效率肯定要高,因为线程间要通过队列来传递数据, 如果10个线程都是Get***,没有这部分内存拷贝(或者内存池分配释放)和数据加锁的开销。 效率当然要高。1其他请求会排队的。 2,应该是得到事件。 3, WINDOWS会跟踪状态。一个线程阻塞了,其他线程会得到 时间处理。

现在的做法是每次调用wsarecv时投递下去的缓冲区长度就是下次希望收到的完整数

据包的长度, 每次GetQueuedCompletionStatus返回后检查缓冲区是否填满,若没填满则继续下次 GetQueuedCompletionStatus调用, 若填满了就调用数据处理流程。

结论: 同步的操作和不费时的操作,尽量放在多线程中执行,需要异步的,比如数据库操作,可以用单独的线程处理(队列),也可以开多个工作线程来处理。

3. IOCP投递数据包顺序的问题:

问题一:

在一个连接上,我投递一个WSASend发送1K的数据出去,这时候下面的缓冲区里却只剩下512字节的空间,这时候,内核就会把这1K数据里的512字节拷贝到缓冲区里发出去,然后在

GetQueueCompleteStatus里返回TRUE,并且在参数里指明只发送了512字节,这时候我们需要继续发送剩下的512字节才能保证把整个1K的数据发送完成,如果在GetQueueCompleteStatus返回后,我们继续发送剩下的512字节的这一个间隙,,刚好另外一个线程投递了一个WSASend发送1K的数据,而这时候下面的缓冲区空了,这1K的数据将被完全发送出去,然后内核才调度到我们继续发送剩下的512字节的这个线程,那么在客户端收到的数据就成了这样: 512字节+1K字节+512字节,而实际上我们希望客户端收到的数据是: 1K(第一次发送的)+1K(第二次WSASend)发送的。 同样,如果多次在一个连接上调用WSARecv,也会出现数据错乱的问题。 使用异步IO的时候,最好能保证上一个IO彻底完成后才继续发出下一个IO。

答:一次只投递一个。在带宽不够的情况下,完成端口没有完成投递给他的-工作就返回了完成包. 问题二:

事情是这样的,网络层使用IOCP,局入网内7千链接,每条链接上每秒平均收发1K数据没问题(每个包的大小小于1K) 当放到外网上,外网服务器是2M带宽独占的,2000个链接,每链接上每秒发送150个字节(已经超过2M的带宽了),IOCP出现数据没有发送完全,却返回了完成包的情况,这个时候查看这条链接上有将近100个包还没有发送出去,不知道大家遇到过这样的情况没有,是不是IOCP的正常情况,有什么解决办法

iocp只是把数据重新拷贝到tcp的缓冲中,返回包中的WSABUF结构中的长度是说明了有多少数据拷贝到tcp的缓冲区中,上层根据这个来决定哪些数据需要重新发送。

答:iocp只是把数据重新拷贝到tcp的缓冲中,返回包中的WSABUF结构中的长度是说明了有多少数据

拷贝到tcp的缓冲区中,上层根据这个来决定哪些数据需要重新发送。完成端口是一种通知机制,你向系统提交一个发送请求,之后就不用管了,系统会维护好数据发送的状态,然后数据全部发送(tcp缓冲区大于或等于要发送的数据)或部分发送之后(tcp缓冲区小于要发送的数据),通知你,这样做的性能提高在于事情是系统去做,系统能够进行最大的优化,比你自己维护要高效多了。

像你所说的,向iocp提交多次请求,一般很少这样做,一般都是提交一次,完成之后再提交,多次提交可能会出问题的,系统不保证多次提交的操作的序列话。

关闭缓冲区只是对于一些对实时要求很高的情况才会关闭,而且即使关闭,TCP那边还是有缓冲,因为有可能丢包需要TCP重新发送。解决办法很简单,那就是一发一收,收到上个包的回复以后发送下一个包。我的理解是WSASend调用返回,但是WSABuf提交的buffer被锁住,直到Get***返回,这个时候buffer被解锁定。 而不是底层收到ack以后WSASend返回。

假设当前一个tcp连接,底层缓冲还剩余100个字节,这个时候你首先提交一个发送操作,发送1000个字节,然后再提交一个操作,50个字节, 能是收到两次发送50个字节的完成通知?

应该是收到一个1000字节返回,和50字节返回的通知,而不是两次50字节的通知。TCP缓冲不够,1000字节发送了100字节出去,Get**不返回,后面提交的100字节请求Get**也不返回,直到socket buffer有空,即使socket buffer有空,也会先COPY那1000个字节剩下的900字节再COPY后提交的100字节,而不会先COPY后来提交的100字节,关于这个,WINDOWS网络编程上有介绍,但是Get返回的两次提交的顺序是没有保证,不保证前提交的请求完成通知先返回。讨论结果就是Get**返回只说明数据COPY到AFD缓冲区里,至于是否发送出去看运气了。假设你刚get**成功,然后网线断开了那就Get**再次返回出错或者你下次调用WSASend/WSARecv出错, TCP有多种机制来控制发送的速度不会超过接收方的处理能力导致网络上大量的包涌塞,滑动窗口机制应该是其中之一。客户端的处理能力也会导致发送方的阻塞,不单单是网络带宽。

4. 消息如何分发

象消息分发,如果使用OO特性的调用,是很消耗时间的,但是我们可以在很消耗时间的地方进行优化,函数调用不用进行寻址,直接运行。可以象下列方式

IOCP发送大数量的问题

1.IOCP发送大数量的问题2.IOCP发送大数量的问题有A,B两块数据,如AB两块数据,如果A数据比较大,异步只发送了一部分就返回了,B数据已经提交,这时候再发A剩下的部分就乱顺序了,该如何处理。所有重叠操作可确保按照应用程序投递的顺序执行.然而,不能确保从完成端口返回的完成通知也按照上述顺序执行\由此可见,
推荐度:
点击下载文档文档为doc格式
0efgr3cisi7d82u9zjlx7yogl1itcy00iqg
领取福利

微信扫码领取福利

微信扫码分享