zoukankan      html  css  js  c++  java
  • windows网络模型

    Windows提供了四种异步IO技术,机制几乎时相同的,区别在于通知结果的方式不同:

    1、通过注册的消息函数进行通知

    2、通过内核event事件进行通知

    3、通过称为完成例程的回调函数进行通知

    4、通过完成端口进行通知

    WSAAsyncSelect

    过程:创建一个套接字后,调用WSAAsyncSelect函数对该套接字注册感兴趣的网络事件,例如accept,read,write等,并且注册对应的Windows 消息,当然要先定义好消息响应函数,这样当某个注册的socket有消息时,就会主动去调用消息响应函数,该函数首先去判断发生了什么网络消息,以及是哪个socket发生了消息,然后调用socket对应的函数进行处理完成了。

    与select的区别

    1、select函数是阻塞的,WSAAsyncSelect是非阻塞的,当没有网络消息时,select会一直阻塞在该函数这里,WSAAsyncSelect则不会。

    2、select是同步的,WSAAsyncSelect是异步的,因为WSAAsyncSelect在有消息响应时会自动去调用消息响应函数,相当于异步的回调函数。

    3、WSAAsyncSelect是基于Windows消息的,参数也需要窗口句柄,需要依赖窗口的存在,所以mfc中的封装类CSocket和CAsyncSocket就是基于WSAAsyncSelect实现的。select是不需要窗口句柄的。

    4、socket被WSAAsyncSelect注册之后,自动变为非阻塞的。而select里的socket还是阻塞的。

    5、select和WSAAsyncSelect所能处理的socket数目是可以调整的,select可以调整FD_SIZE来改变数目,WSAAsyncSelect只要消息能响应及时就没问题。

    WSAEventSelect

    过程:每得到一个新的socket,调用WSACreateEvent就创建一个内核事件,然后调用WSAEventSelect将该内核事件与socket绑定起来,用两个数组,一个用来存储socket,一个用来存储对应的event,位置要一一对应,创建好之后调用WSAWaitForMultipleEvents来等待event数组,有event事件时,该函数返回有消息事件在数组中的索引,根据索引得到有消息的socket和event,并判断出是发生了什么网络消息,然后再进行处理就可以了。

    说明

    1、该模型是基于event内核事件的,因此不像基于WSAAsyncSelect基于消息那样需要有窗口才行。

    2、调用WSAEventSelect之后,socket也是变为非阻塞的。

    3、受WSAWaitForMultipleEvents的限制,该函数一次最多只能处理64个事件对象。因此如果想要多于这个数目,一种方法是加开线程.

     

    重叠IO

    过程:得到一个新的socket连接时,为该socket创建一个重叠IO和event事件,绑定起来,然后用WSARecv投递调用,调用WSAWaitForMultipleEvents函数等待与重叠IO关联在一起的事件变为已触发状态,WSAWaitForMultipleEvents返回后,调用WSAResetEvent函数,将该事件对象恢复为未触发态。调用WSAGetOverlappedResult函数判断重叠IO的完成状态。处理完之后重新调用WSARecv投递请求。上面是通过事件通知的过程,也可以完成例程即在WSARecv中注册回调函数来完成消息通知。

    说明

    1、重叠IO延续了win32 IO模型。从发送和接收的角度来看,重叠IO模型与前面介绍的Select模型、WSAAsyncSelect模型和WSAEventSelect模型都不同。因为在这三个模型中IO操作还是同步的,例如:在应用程序调用recv函数时,都会在recv函数内阻塞,直到接收数据完毕后才返回。而重叠IO模型会在调用recv后立即返回。等数据准备好后再通知应用程序。

    2、系统向应用程序发送通知的形式有两种:一是事件通知。二是完成例程。后面将会介绍这两种形式。

    3、在Windows socket中,接收数据的过程可以分为:等待数据和将数据从系统复制到用户空间两个阶段。各种IO模型的区别在于这两个阶段上。

    前三个模型的第一个阶段的区别: select模型利用select函数主动检查系统中套接字是否满足可读条件。WSAAsyncSelect模型和WSAEventSelect模型则被动等待系统的通知。

    第二个阶段的区别:此阶段前三个模型基本相同,在将数据从系统复制到用户缓冲区时,线程阻塞。而重叠IO与它们都不同,应用程序在调用输入函数后,只需等待接收系统完成的IO操作完成通知。

     

    iocp

    过程

    1、创建一个服务线程,调用WSASocket创建监听套接字,并完成固定的初始化过程,使用WSAAccept开始监听,开始监听

    2、事先调用CreateIoCompletionPort创建一个完成端口,当收到请求socket之后,在调用这个函数将它加入到完成端口队列中,

    3、加入之后,还要为该socket创建一个接收的重叠IO和缓存,然后通过WSARecv函数将套接字,重叠IO和缓存一起投递出去

    4、上面就是服务线程的处理流程,接下来开启多个工作线程,来处理每个连接

    5、在工作者线程中,调用GetQueuedCompletionStatus函数不断查询各IO状态,当有IO有消息时,该函数返回,并返回有消息的IO和套接字,拿出数据之后,对IO进行初始化之后,再通过WSARecv函数把这个IO投递进去准备接收下一个网络消息。

    说明

    1、这里的异步在于把一个分配了重叠IO和缓存空间的socket放进IOCP之后,就不需要对这个连接进行专门的处理,接下里就是通用的操作,不断的查询IOCP队列里各连接的状态,当IOCP在系统内部完成数据处理,把数据放到该连接的缓存空间之后,才发出消息通知,然后端口函数把重叠IO从队列中取出,得到里面的数据处理,然后清空数据,再把这个重叠投递到队列里,接收下一次的消息。

    2、使用重叠IO可以直接得到数据,避免了阻塞recv中将数据从系统空间复制到用户空间这一阻塞过程。这只是它效率高的一个因素,它还维护一个队列,来自动监控是否有消息到来,每个线程能处理的队列的数目是没有限制,要看实际效果而定,同时灵活方便扩展线程,用一个线程或几个线程都可以,当然线程数目也要考虑到CPU的数目。并且重叠IO利用事件通知时,每个线程有64的限制,使用完成例程的回调函数,这样多线程的优势就得不到利用。

     

     

  • 相关阅读:
    autocomplete自动完成搜索提示仿google提示效果
    实现子元素相对于父元素左右居中
    javascript 事件知识集锦
    让 IE9 以下的浏览器支持 Media Queries
    「2013124」Cadence ic5141 installation on CentOS 5.5 x86_64 (limited to personal use)
    「2013420」SciPy, Numerical Python, matplotlib, Enthought Canopy Express
    「2013324」ClipSync, Youdao Note, GNote
    「2013124」XDMCP Configuration for Remote Access to Linux Desktop
    「2013115」Pomodoro, Convert Multiple CD ISO to One DVD ISO HowTo.
    「2013123」CentOS 5.5 x86_64 Installation and Configuration (for Univ. Labs)
  • 原文地址:https://www.cnblogs.com/suntp/p/6483700.html
Copyright © 2011-2022 走看看