设为首页 收藏本站
查看: 1177|回复: 0

[经验分享] Windows完成端口 IOCP模型(一)

[复制链接]

尚未签到

发表于 2018-6-16 09:31:41 | 显示全部楼层 |阅读模式
  1 Windows完成端口基本介绍
  2他是只能在Windows下的基于SOCKET事件管理的模型
  3与select不同,select需要多次重置管理句柄,IOCP只要一次
  4有事件后select需要操作获取数据,而IOCP通知你的时候说明数据操作好了
  5select管理句柄的数目有限,IOCP没有限制
  6IOCP支持多线程同时等待。
  我的设计思路一个线程用来侦听accept事件, 一个线程来侦听SOCKET的IO事件,
  大部分框架都是这样, 其实可以只使用一个线程做异步SOCKET就完全足够了,现在
  使用多线程来 就是看看这个IOCP的多线程用法,
  在这之前先要了解下 异步通信 和 重叠I/O模型
  异步通信机制: http://blog.51cto.com/blogger/draft/412685
  重叠I/O模型: http://blog.51cto.com/12158490/2058180
  我建议使用单线程 原因: 应为多个线程,拿到数据后,还是要发送到另外一个线程里面去,
  然后做成事件队列, 也就是你线程拿到数据后, 还是要按队列线程,进行逻辑处理,多线程没意义。
  
  
  2完成端口内部运行流程
  完成端口的做法:事先开好几个线程,你有几个CPU我就开几个,首先是避免了线程的上下文切换,因为线程想要
  执行的时候,总有CPU资源可用,然后让几个线程等着,等到有用户请求到来的时候,就把这些请求都加入到一个
  公共消息队列中, 然后这几个开好的线程就排队逐一去从消息队列中取出消息并加以处理, 这种方式实现了
  异步通信和负载均衡的问题,因为他提供了一种机制来使用几个线程"公平的"处理来自多个客户端的输入/输出
  ,并且线程如果没事干的时候,也会被系统挂起,不会占用CPU
  
  
  3WSAAsyncSelect或者WSAEventSelect和完成端口
  WSAAsyncSelect或者WSAEventSelect两种异步模型, 这两种模式一定没有使用overlapped(重叠)机制,
  就不能算是真正的异步,可能是其内部维护了一个消息队列,这两个模式虽然实现了异步接收,却不能异步的发送,
  完成端口他是先把用户数据接收回来后在通知用户直接来取,而这两种模式只会接到数据到达的通知,只能是由
  应用程序自己去recv数据,性能上就发送了差异
  要实现异步通信, 就要一个很强的I/O数据结构,叫重接结"Overtlapped",
  Window所有异步通信都是基于他,完成端口也不例外
  
  就是执行I/O请求的时间与线程执行其他任务的事件是重叠(overlapped)的,
  重叠结构是异步通信机制实现的一个核心数据结构,因为几乎所有的网络操作例如发送/接收,都要用
  WSASend()和WSARecv()代替,参数里面都会要附带一个重叠结构,因为重叠机构可以理解为是一个
  网络操作的ID号,也就是说我们要利用重叠I/O提供的异步机制的话,每一个网络操作都要有一个唯一的ID号,
  因为进来系统内核,一看到有重叠的I/O的调用进来了,就会使用其异步机制,并且操作系统就只能靠
  这个重叠结构带有的ID号来区分是哪一个网络操作了,然后内核里处理完毕, 根据这个ID号,把对应的数据传上去.
  4完成端口基本的使用流程
  完成端口也分步骤的
  1调用CreateIoCompletionPort()函数创建一个完成端口,而且在一般情况下,我们需要并且只需要
  建立一个完成端口,把他的句柄保存好, 之后只要使用这一个句柄就行了。
  2根据和客户的I/O操作最好是自己建一个工作线程
  3接入Socket连接, 有两种方式,1是和别的模型一样,有一个独立的线程,专门来accept客户端的连接,
  二是用性能更好的异步AcceptEx()请求
  4每当有客户端进来的时候,还是调用CreateIoCompletionPort()函数,这里不是建立完成端口,
  而是把新连入的Socket句柄, 和你创建的完成端口绑定在一起。
  5客户端连入后,我们要向这个客户端Socket提交一个请求,如接收文件要调用WSARecv()然后系统
  就会去执行接收数据的操作, 就不用我们管了。
  6 然后就要调用GetQueuedCompletionStatus()(是一个阻塞函数)里面是扫描端口的队列里是否有
  网络通信的请求存在(例如读取数据,发送数据等),一旦有,就会将这个请求从完成端口的队列取回来,
  继续执行本线程的后续代码,处理完毕后, 必须要再次 投递网络通信请求(WSARecv),如此循环。
  5AcceptEx和Accept的区别
  AcceptEx和Accept最大的区别,就是取消了阻塞方式的accept调用,也就是说AccentEx也是通过
  完成端口来异步完成的。
  这样做的好处就是:如果短时间内客户端并发连接请求不是很多,accept和AcceptEx在性能上区别不大,
  虽然我们创建Socket只用一行SOCKET s =socket(...)一行代码,但是系统内部建立一个Socket是相当
  耗费资源的,因为Winsock2是分层的机构体系,创建一个Socket需要用到多个Provider之间进行处理,
  最终形成一个可用的套接字,总之,创建一个Socket的开心是相当高的。
  AcceptEx比Accept强三点:
  (1)最关键的是AcceptEx在客户端连入之前,就把客户端的Socket建立好了,也就是说,AcceptEx是先建立
  Socket,然后发出的AcceptEx调用,也就是说,在进行客户端的通信之前,无论是否有客户端连入,
  Socket都是提前建立好的,而不需要想accept是在客户端连入之后,在现场话费时间建立Socket,
  (2)相比Accept只能阻塞方式建立一个连入的入口,对于大量的并发客户端来讲,是在是有点挤,
  而AcceptEx可以在完成端口上投递多个请求,还有客户端连入的时候,就非常优雅而且从容.
  (3)AcceptEx还有一个优点,就是投递AccepEx的时候,收取客户端发来的第一组数据,这是同时
  进行的, 也就意味着,如果客户端只是连入但不发送数据的话,我们就不会收到这个AccepeEx完成的通知,
  异步的AcceptEx使用起来比accept要麻烦。
  由于时间关系,在下篇博客 会详细介绍完成端口的用法
  实现图片中的功能
DSC0000.jpg

  参考博客地址 http://www.cnblogs.com/lancidie/archive/2011/12/19/2293773.html
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-524451-1-1.html 上篇帖子: Windows的资源监视器 下篇帖子: Windows Server 2008 【***基本配置】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表