六种Socket I/O模型幽默讲解

老陈有一个在外地工做的女儿,不能常常回来,老陈和她经过信件联系。他们的信会被邮递员投递到他们的信箱里。html

这和Socket模型很是相似。下面就以此为例讲解Socket I/O模型。数组

零:阻塞模型

老陈很是想看女儿的信,以致于他什么都不作,就站在门口等。直到接到邮递员给他的信件才开心的看信回信。服务器

这就是阻塞模型,进程阻塞在socket的接收函数上。网络

 

一:select模型

可是不吃不喝一直站门口等着总不行吧。因此他每隔10分钟就下楼检查信箱,看是否有女儿的信 。数据结构

在这种状况下,“下楼检查信箱“ 而后回到楼上耽误了老陈太多的时间,以致于老陈没法作其余工做。多线程

select模型和老陈的这种状况很是类似:周而复始地去检查…… 若是有数据……接收/发送 …….并发

服务器的几个主要动做以下:app

  1. 建立监听套接字,绑定,监听;
  2. 建立工做者线程;
  3. 建立一个套接字数组,用来存放当前全部活动的客户端套接字,每accept一个链接就更新一次数组;
  4. 接受客户端的链接。

 

二:WSAAsyncSelect 异步选择模型

后来,老陈使用了微软公司的新式信箱。这种信箱很是先进,一旦信箱里有新的信件,盖茨就会给老陈打电话:喂,大爷,你有新的信件了!今后,老陈不再必频繁上下楼检查信箱了,牙也不疼了,你瞅准了,蓝天 ……不是,微软~~~~~~~~
微软提供的WSAAsyncSelect模型就是这个意思。异步

WSAAsyncSelect模型是Windows 下最简单易用的一种Socket I/O模型。使用这种模型时,Windows会把网络事件以消息的形式通知应用程序。socket

服务器的几个主要动做以下:

  1. 在WM_CREATE消息处理函数中,初始化Windows Socket library,建立监听套接字,绑定,监听,而且调用WSAAsyncSelect函数表示咱们关心在监听套接字上发生的FD_ACCEPT事件;
  2. 自定义一个消息WM_SOCKET,一旦在咱们所关心的套接字(监听套接字和客户端套接字)上发生了某个事件,系统就会调用WndProc而且message参数被设置为WM_SOCKET;
  3. 在WM_SOCKET的消息处理函数中,分别对FD_ACCEPT、FD_READ和FD_CLOSE事件进行处理;
  4. 在窗口销毁消息(WM_DESTROY)的处理函数中,咱们关闭监听套接字,清除Windows Socket library

特色:须要创建一个窗口用于接收消息。

 

三:WSAEventSelect 模型

后来,微软的信箱很是畅销,购买微软信箱的人以百万计数……以致于盖茨天天 24小时给客户打电话,累得腰酸背痛,喝蚁力神都很差使~~~~~~
微软改进了他们的信箱:在客户的家中添加一个附加装置,这个装置会监视客户的信箱,每当新的信件来临,此装置会发出 “新信件到达”声,提醒老陈去收信。盖茨终于能够睡觉了。

服务器的几个主要动做以下:

  1. 感兴趣的一组网络事件建立一个事件对象,再调用WSAEventSelect函数将网络事件和事件对象关联起来。
  2. 当网络事件发生时,winsock使响应的事件对象受信,在事件对象上等待的函数就会当即返回。
  3. 调用WSAEnumNetworkEvents函数即可得到到底发生了什么网络事件(FD_READ/FD_ACCEPT/FD_CLOSE等等)。

特色:最多能够支持WSA_MAXIMUM_WAIT_EVENTS个对象,他的大小是64。

 

四:Overlapped I/O 事件通知模型

后 来,微软经过调查发现,老陈不喜欢上下楼收发信件,由于上下楼其实很浪费时间。因而微软再次改进他们的信箱。新式的信箱采用了更为先进的技术,只要用户告诉微软本身的家在几楼几号,新式信箱会把信件直接传送到用户的家中,而后告诉用户,你的信件已经放到你的家中了!老陈很高兴,由于他没必要再亲自收发信件 了!

Overlapped I/O 事件通知模型和WSAEventSelect模型在实现上很是类似,主要区别在”Overlapped”,Overlapped 模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个 Winsock I/O请求。这些提交的请求完成后,应用程序会收到通知。什么意思呢?就是说,若是你想从 socket上接收数据,只须要告诉系统,由系统为你接收数据,而你须要作的只是为系统提供一个缓冲区 ~~~~~

 

五:Overlapped I/O 完成例程模型

老陈接收到新的信件后,通常的程序是:打开信封—-掏出信纸 —-阅读信件—-回复信件 ……为了进一步减轻用户负担,微软又开发了一种新的技术:用户只要告诉微软对信件的操做步骤,微软信箱将按照这些步骤去处理信件,再也不须要用户亲自拆信 /阅读/回复了!老陈终于过上了小资生活!

Overlapped I/O 完成例程要求用户提供一个回调函数,发生新的网络事件的时候系统将执行这个函数。

特色:由I/O来完成socket的拆包工做,实现异步。

 

六:IOCP 完成端口模型

微软信箱彷佛很完美,老陈也很满意。可是在一些大公司状况却彻底不一样!这些大公司有数以万计的信箱,每秒钟都有数以百计的信件须要处理,以致于微软信箱常常因超负荷运转而崩溃!须要从新启动!微软不得不使出杀手锏 ……
微软给每一个大公司派了一名名叫”Completion Port”的超级机器人,让这个机器人去处理那些信件!

特色:动用一个合理数量的线程来接受信息,而后把信息投送到应用程序。

“Windows NT小组注意到这些应用程序的性能没有预料的那么高。特别的,处理不少同时的客户请求意味着不少线程并发地运行在系统中。由于全部这些线程都是可运行的 [没有被挂起和等待发生什么事], Microsoft意识到NT内核花费了太多的时间来转换运行线程的上下文[Context],线程就没有获得不少CPU时间来作它们的工做。你们可能也都感受到并行模型的瓶颈在于它为每个客户请求都建立了一个新线程。建立线程比起建立进程开销要小,但也远不是没有开销的。咱们不妨设想一下:若是事先开好 N个线程,让它们在那hold[堵塞 ],而后能够将全部用户的请求都投递到一个消息队列中去。而后那N 个线程逐一从消息队列中去取出消息并加以处理。就能够避免针对每个用户请求都开线程。不只减小了线程的资源,也提升了线程的利用率。理论上很不错,你想我等泛泛之辈都能想出来的问题, Microsoft又怎会没有考虑到呢?”—– 摘自nonocast的《理解I/O Completion Port》

 

转载:https://www.cnblogs.com/jikebiancheng/p/6225009.html

相关文章
相关标签/搜索