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的限制,使用完成例程的回调函数,这样多线程的优势就得不到利用。

windows网络模型的更多相关文章

  1. windows网络模型之完成端口(CompletionPort)详解 (转)

    转载自:https://blog.csdn.net/piggyxp/article/details/6922277 目录: 1. 完成端口的优点 2. 完成端口程序的运行演示 3. 完成端口的相关概念 ...

  2. windows网络模型之重叠IO(完成例程)的使用

    #include <WINSOCK2.H> #include <stdio.h> #define PORT 5150 #define MSGSIZE 1024 #pragma ...

  3. windows网络模型之重叠IO的使用

    大部分内容转载自https://blog.csdn.net/piggyxp/article/details/114883 目录: 1. 重叠模型的优点 2. 重叠模型的基本原理 3. 关于重叠模型的基 ...

  4. Windows完成端口网络模型

    GetQueuedCompletionStatus  比如此时端口上完成的是什么操作,数据是什么等,还有,系统如何做到自动填充上述的结构的,也就是说,系统怎么知道在Overlap->OpCode ...

  5. 【神经网络与深度学习】深度学习实战——caffe windows 下训练自己的网络模型

    1.相关准备 1.1 手写数字数据集 这篇博客上有.jpg格式的图片下载,附带标签信息,有需要的自行下载,博客附带百度云盘下载地址(手写数字.jpg 格式):http://blog.csdn.net/ ...

  6. Kinect for Windows SDK开发入门(十九):Kinect Fusion

        Kinect for Windows SDK1.7中引入了Kinect Fusion功能.在1.8的SDK中对该功能进行了改进和强化,Kinect Fusion能够使得我们使用Kinect f ...

  7. [No000054] Windows 下Python3.5, NoteBook增强版安装

    接着上周继续,没看的童鞋.请移步: http://www.cnblogs.com/Chary/p/No00004B.html 这里,假设你已经能够看到这个画面了: 接下来,我们继续 给药 : 安装no ...

  8. Windows网络驱动、NDIS驱动(微端口驱动、中间层驱动、协议驱动)、TDI驱动(网络传输层过滤)、WFP(Windows Filtering Platform)

    catalog . 引言 . Windows 2000网络结构和OSI模型 . NDIS驱动 . NDIS微端口驱动编程实例 . NDIS中间层驱动编程实例 . NDIS协议层驱动编程实例 . TDI ...

  9. Chapter 6 Windows下编译pycaffe

    pycaffe 是 Caffe 提供的Python接口,我们知道 Caffe 的整个framework是基于C Plus Plus 来开发的,所以pycaffe 的根本就是提供Python调用Caff ...

随机推荐

  1. 常量的三种定义方式和static在c语言中的三种修饰

    c语言的常量在执行期间为固定值,在定义后无法被修改常量可以是任何的数据基本类型,可以为整形,浮点常量,字符和字符串常量1,使用const关键字2, 使用宏定义3,使用枚举常量 枚举: #include ...

  2. char[] 转换string时的自动截断问题

    在char[] 转换string时可以直接转换,但当用char[]读取一个二进制文件之后,若char[] 中包含有'\0'时,在转换时会被string检测到并认为字符串末尾,后面内容会被截断,导致转换 ...

  3. 洛谷P4526 【模板】自适应辛普森法2(simpson积分)

    题目描述 计算积分 保留至小数点后5位.若积分发散,请输出"orz". 输入输出格式 输入格式: 一行,包含一个实数,为a的值 输出格式: 一行,积分值或orz 输入输出样例 输入 ...

  4. 8-IdentityServer4登录中心

    1-新建webapi  IdentityServer4服务器项目 E:\coding\netcore\IdentityServerSample>dotnet new webapi --name ...

  5. nodejs 文件系统

    nodejs访问文件系统   所有的文件系统的调用,都需要加载fs模块,即var fs=require('fs'); nodejs提供的fs模块几乎所有的功能都有两种形式选择:异步和同步,如异步的wr ...

  6. hdu1848Fibonacci again and again(sg函数)

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  7. OSG-简单模型控制

    本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html 作者写的比较好,再次收藏,希望更多的人可以看到这个文章 互联网是是一个相 ...

  8. Appium的环境搭建和配置

    Appium的环境搭建和配置 一.安装Nodejs 下载nodejs安装包(https://nodejs.org/en/download/)安装 下载后,双击安装文件,按提示来安装. 测试安装是否成功 ...

  9. lesson 22 by heart

    lesson 22 by heart on end = continuously 连续不断地 know/learn sth by heart 记忆sth falter: speak hesitantl ...

  10. Nginx与Ribbon的区别

    服务器端负载均衡 Nginx Nginx 基于C语言,快速,性能高5w/s. Redis 5w/s,RibbatMQ 1.2w/s ApacheActiveMQ 0.6w/s 业务系统,kafka 2 ...