IOCP网络包重组问题

     目前,IOCP已经广泛用于网络程序设计了,由于IOCP基本多线程对网络数据进行接收,因为数据包的重组往往成功程序员处理IOCP最难做的事情, 近来在做相交的项目,也颇费了一番心思,现把我的处理方法写下来。

     由于TCP连接传输数据会把数据包是流的方式进行,因为,我们在客户端接收数据时,每次recv函数结束得到的并不一定是我们以前每次调用send函数所发送的完整数据,但TCP传输数据的顺序是不会变的。根据这两个性质,我们需要做以下事情,

  一、因为TCP不是分包传输,所以我们需要自己构造数据包头来标识数据的起始位置和数据包的大小;

  二、由于数据传输的顺序是不变的,因此,只要我们保证接收时接收数据的顺序不变,再根据数据包头中的标志和数据数据包的大小就肯定能确定一个完整的数据包。

  因此,我们需要先设计自己的数据包头,这个没有什么说的,第二件事,保证数据接收的顺序不变比较麻烦,因为有多个线程进行数据的接收,要保证顺序性,我们就要对多个线程进行互斥操作,保证某一连接不能同时有多个线程进行数据的接收,为了兼顾效率,我们也应保证在数据接收操作完成后,应立刻允许其它线程对此连接进行数据的接收操作。

  保证一个连接同时只有一个线程接收,我们可以只对一个连接投递一个接收请求,当有数据到来时,启动一个线程进行接收数据,此时,此连接已经没有别的接收请求了,所以就是有数据到达时,也不会启动别的线程在此连接上接收数据,当接收数据的线程完成操作时,再投递接收数据的请求,就可以允许别的线程在连此连接上接收数据了,这样我们就保证了一个连接上接收数据操作的互斥性。

  为了尽快让其它线程对此连接进行数据,我对每个连接都建立一个临时数据的缓冲区和一个变量,指向此缓冲区中数据的长度,当有数据接收后,先放入此缓冲区中数据的后面,然后判断是否有一个完整的数据包(根据数据包头和数据包的长度),如果是完整的数据包,则所有完整的数据从此缓冲区移出,同时调整变量为移后数据的长度,这时便可以投递接收请求,让别的线程进行数据的接收工作,而当前线程可以根据需要处理移出来的数据包。

  由于一个线程从接收数据到投递接收请求这段时间,所处理的操作比较少(就接收数据,移去完整的数据包),所以效率上是可以保证的。而且其中不会有可能使线程挂起或睡眠的操作,所以一般情况下不会产出线程的切换,不会产生额外的开销。下面是数据接收流程图,这个流程图中画的比较多,还把线程移走完整数据后所做的别的操作都画了出来。

 

  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注:更多资料请根据压缩文件中的《更多资料.txt》文件的介绍免费获取 =====★★★★史上最全的IOCP资料大全★★★★============== 目的:研究和分享基于IOCP通讯模型的服务器端及即时通讯客户端相关技术 语言:Delphi\C++ 欢迎给位朋友加入 -------------------------前言------------------------ 最近在编写即时通讯工具,于是便参考和搜罗了网上大量的文章和源码, 对IOCP涉及的相关技术进行了广泛和深入的研究。 IOCP涉及的关键知识点有很多很多,这方面的文章也非常多, 但是很多讲述的都是某方面的,为了帮大家甄选资料,我决定分享给大家。 以下是我搜集的部分IOCP相关的资料目录,有需要的请加我QQ和QQ群,无偿分享: --------------------------IOCP部分相关知识点------------------ 线程池,Socket连接池、数据库连接池、内存池及内存管理 防DDos攻击、防只连接不发送消息及Setsockopt相关设置 WSAENOBUFS及0缓冲的WSARecive投递 优雅的链接关闭方法及shutdown、TIME_WAIT 及注册表设置:TcpNumConnections/MaxUserPort 多核多线程、生产消费者模型、读写者模型、多线程无锁环形队列及LockFreeList概念 Socket重用、端口重用 心跳、粘、乱序 ------------------------我收集的文章及源码的部分目录---------------------- ------------------------供大家搜索资料时参考----------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值