WinSock 异步I/O模型-1
异步选择(WSAAsyncSelect):异步选择基本定义
- 异步选择(WSAAsyncSelect)模型是一个有用的异步 I/O 模型。利用这个模型,应用程序可在一个套接字上,接收以 Windows 消息为基础的网络事件通知。具体的做法是在建好一个套接字后,调用WSAAsyncSelect函数。
- WSAAsyncSelect模型是Select模型的异步版本,在调用select()函数时,会发生阻塞现象。可以通过select()函数timeout参数,设置函数调用的阻塞时间。在设定的时间内,线程保持等待,直到其中一个或多个套接字满足可读可写的条件时,该函数返回。
- 该模型的核心即是WSAAsyncSelect函数,该函数是非阻塞的。
- 要想使用 WSAAsyncSelect 模型,在应用程序中,必须有一个窗口,且该窗口有一个窗口例程函数(WinProc)。
- 与select模型比较:
相同点:他们都可以对Windows套接字应用程序所使用的多个套接字进行有效的管理。
不同点: 1.WSAAsyncSelect模型是异步的。在应用程序中调用WSAAsyncSelect()函数,通知系统感兴趣的网络事件,该函数立即返回,应用程序继续执行;
2.发生网络事件时,应用程序得到的通知方式不同。Select()函数返回时,说明某个或者某些套接字满足可读可写的条件,应用程序需要使用FD_ISSET宏,判断套接字是否存在可读可写集合中。而对于WSAAsyncSelect模型来说,当网络事件发生时,系统向应用程序发送消息。
3.WSAAsyncSelect模型应用在基于消息的Windos环境下,使用该模型时必须创建窗口。而Select模型广泛应用在Unix系统和Windows系统,使用该模型不需要创建窗口。
4.应用程序调用WSAAsyncSelect()函数后,自动将套接字设置为非阻塞模式。而应用程序中调用select()函数后,并不能改变套接字的工作方式
- 下面,开始介绍一下WSAAsyncSelect 的函数原型与具体使用方法:
int WSAAsyncSelect(
__in SOCKET s,
__in HWND hWnd,
__in unsigned int wMsg,
__in long lEvent );
● s 参数指定的是我们感兴趣的那个套接字。
● hWnd 参数指定一个窗口句柄,它对应于网络事件发生之后,想要收到通知消息的那个窗口。
● wMsg 参数指定在发生网络事件时,打算接收的消息。该消息会投递到由hWnd窗口句柄指定的那个窗口。(通常,应用程序需要将这个消息设为比Windows的WM_USER大的一个值,避免网络窗口消息与系统预定义的标准窗口消息发生混淆与冲突)
● lEvent 参数指定一个位掩码,对应于一系列网络事件的组合,大多数应用程序通常感兴趣的网络事件类型包括: FD_READ、FD_WRITE、FD_ACCEPT、FD_CONNECT、FD_CLOSE。当然,到底使用FD_ACCEPT,还是使用FD_CONNECT类型,要取决于应用程序的身份是客户端,还是服务器。如应用程序同时对多个网络事件有兴趣,只需对各种类型执行一次简单的按位OR(或)运算,然后将它们分配给lEvent就可以了,例如: WSAAsyncSeltct(s, hwnd, WM_SOCKET, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE);
解释说明:我们的应用程序以后便可在套接字s上,接收到有关连接、发送、接收以及套接字关闭这一系列网络事件的通知。
FD_READ 应用程序想要接收有关是否可读的通知,以便读入数据
FD_WRITE 应用程序想要接收有关是否可写的通知,以便写入数据
FD_ACCEPT 应用程序想接收与进入连接有关的通知
FD_CONNECT 应用程序想接收与一次连接完成的通知
FD_CLOSE 应用程序想接收与套接字关闭的通知
- 需要注意的地方:
- 注意①: 多个事件务必在套接字上一次注册! 另外还要注意的是,一旦在某个套接字上允许了事件通知,那么以后除非明确调用closesocket命令,或者由应用程序针对那个套接字调用了WSAAsyncSelect,从而更改了注册的网络事件类型,否则的话,事件通知会永远有效!若将lEvent参数设为0,效果相当于停止在套接字上进行的所有网络事件通知。
- 注意 ②: 若应用程序针对一个套接字调用了WSAAsyncSelect,那么套接字的模式会从“锁定”变成“非锁定”。这样一来,如果调用了像WSARecv这样的Winsock函数,但当时却并没有数据可用,那么必然会造成调用的失败,并返回WSAEWOULDBLOCK错误。为防止这一点,应用程序应依赖于由WSAAsyncSelect的uMsg参数指定的用户自定义窗口消息,来判断网络事件类型何时在套接字上发生;而不应盲目地进行调用。
- 注意 ③:应用程序如何对 FD_WRITE 事件通知进行处理。 只有在三种条件下,才会发出 FD_WRITE 通知: ■ 使用 connect 或 WSAConnect,一个套接字首次建立了连接。 ■ 使用 accept 或 WSAAccept,套接字被接受以后。 ■ 若 send、WSASend、sendto 或 WSASendTo 操作失败,返回WSAEWOULDBLOCK 错误,而且缓冲区的空间变得可用。 因此,作为一个应用程序,自收到首条 FD_WRITE 消息开始,便应认为自己必然能在一个套接字上发出数据,直至一个send、WSASend、sendto 或 WSASendTo 返回套接字错误 WSAEWOULDBLOCK。经过了这样的失败以后,要再用另一条 FD_WRITE 通知应用程序再次发送数据。
- 应用程序在一个套接字上成功调用了WSAAsyncSelect之后,会在与hWnd窗口句柄对应的窗口例程中,以Windows消息的形式,接收网络事件通知。
- 窗口例程通常定义如下:
- LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg,
- WPARAM wParam,
- LPARAM lParam );
- ● hWnd 参数指定一个窗口的句柄,对窗口例程的调用正是由那个窗口发出的。
- ● uMsg 参数指定需要对哪些消息进行处理。这里我们感兴趣的是WSAAsyncSelect调用中定义的消息。
- ● wParam 参数指定在其上面发生了一个网络事件的套接字。假若同时为这个窗口例程分配了多个套接字,这个参数的重要性便显示出来了。
- ● lParam参数中,包含了两方面重要的信息。其中, lParam的低字(低位字)指定了已经发生的网络事件,而lParam的高字(高位字)包含了可能出现的任何错误代码。
- 步骤:网络事件消息抵达一个窗口例程后,应用程序首先应检查lParam的高字位,以判断是否在网络错误。 这里有一个特殊的宏: WSAGETSELECTERROR,可用它返回高字位包含的错误信息。 若应用程序发现套接字上没有产生任何错误,接着便应调查到底是哪个网络事件类型,具体的做法便是读取lParam低字位的内容。 此时可使用另一个特殊的宏:WSAGETSELECTEVENT,用它返回lParam的低字部分。
- 总结一下,WSAAsyncSelect模型的优势和不足:
- 优势: 1.该模型的使用方便了在基于消息的Windows环境下开发套接字的应用程序。开发人员可以像处理其他消息一样对网络事件消息进行处理。
- 2.该模型确保接收所有数据提供了很好的机制。通过注册FD_CLOSE网络事件,从容关闭服务器与客户端的连接保证了数据全部接收。
- 不足: 1.该模型局限在,他基于Windows的消息机制,必须在应用程序中创建窗口。当然,在开发中可以根据具体情况是否显示该窗口。MFC的CSocketWnd类就是用来创建一个不显示的窗口,并在该类中声明接收网络事件消息处理函数。
- 2.由于调用WSAAsyncSelect()函数后,自动将套接字设置为非阻塞状态。当应用程序为接收到网络事件调用相应函数时,未必能够成功返回。这无疑增加了开发人员使用该模型的难度。对于这一点可以从MFC CSocket类的Accept()、Receive()和Send()函数的实现得到验证。
WinSock 异步I/O模型-1的更多相关文章
- WinSock 异步I/O模型 转载
如果你想在Windows平台上构建服务器应用,那么I/O模型是你必须考虑的.Windows操作系统提供了五种I/O模型,分别是: ■ 选择(select):■ 异步选择(WSAAsyncSelect) ...
- WinSock 异步I/O模型-3
重叠I/O(Overlapped I/O) 在 Winsock 中,重叠 I/O(Overlapped I/O)模型能达到更佳的系统性能,高于之前讲过的三种.重叠模型的基本设计原理便是让应用程序使用一 ...
- WinSock 异步I/O模型-2
事件选择(WSAEventSelect): WSAEventSelect模型是Windows Sockets提供的另外一个有用的异步I/O模型.该模型允许一个或多个套接字上接收以事件为基础的网络事件通 ...
- WinSock 异步I/O模型
如果你想在Windows平台上构建服务器应用,那么I/O模型是你必须考虑的. Windows操作系统提供了五种I/O模型,分别是选择(select)模型,异步选择(WSAAsyncSelect)模型, ...
- 阻塞与非阻塞、同步与异步 I/O模型
I/O模型 Linux 下的五种I/O模型 阻塞I/O(blocking I/O) 非阻塞I/O (nonblocking I/O) I/O复用(select 和poll) (I/O multiple ...
- 【转】深入浅出异步I/O模型
转自:http://pengpeng.iteye.com/blog/868643 从上篇文章的介绍我们知道linux内核根据TCP/IP网络模型,给我们隐藏了传输层以下的网络传输细节,我们的网络应用程 ...
- 磁盘IO的性能指标 阻塞与非阻塞、同步与异步 I/O模型
磁盘IO的性能指标 - 蝈蝈俊 - 博客园https://www.cnblogs.com/ghj1976/p/5611648.html 阻塞与非阻塞.同步与异步 I/O模型 - 蝈蝈俊.net - C ...
- 阻塞 , 非阻塞 , 同步 ,异步 , I/O模型
•阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否需要等待: •同步,异步:访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞:异步只需要I/O操作完成的通知,并不主动读写 ...
- Python的异步编程[0] -> 协程[1] -> 使用协程建立自己的异步非阻塞模型
使用协程建立自己的异步非阻塞模型 接下来例子中,将使用纯粹的Python编码搭建一个异步模型,相当于自己构建的一个asyncio模块,这也许能对asyncio模块底层实现的理解有更大的帮助.主要参考为 ...
随机推荐
- iBrand 产品工具包:Laravel Database Logger
iBrand 社交新零售电商产品从2016年9月启动至今,已经趋于稳定,而且已经初步得到市场的检验,特别能抗住电商中秒杀时高并发的交易场景. 接下来我们团队会逐步开源一些正在使用的工具和解决方案,并且 ...
- linux kvm虚拟机快速构建及磁盘类型
KVM命令管理 virsh命令:用来管理各虚拟机的接口命令查看/创建/停止/关闭...支持交互模式格式:virsh 控制指令 [虚拟机名称] [参数] [root@room1pc01 桌面]# vir ...
- SQL Server使用侦听器IP访问时遇到"The target principal name is incorrect. Cannot generate SSPI context"
在测试SQL Server 2016 Always On时,在创建侦听器后,在客户端使用SSMS, 可以用侦听器名称访问Always On集群,但是使用侦听器IP访问时遇到"The targ ...
- Ubuntu 上查看硬件信息命令
1.Mint 驱动程序管理器是由 Linux Mint 团队开发的一款系统工具软件,使得用户在Linux系统中可容易安装专有驱动,通过一个直观的界面.由于 Mint 驱动程序管理器具有独立性,它支持所 ...
- 【linux】linux下能ping通ip 但是不能ping通域名
经过一翻查找后解决了,原因和方法如下: [root@~]# grep host /etc/nsswitch.conf#hosts: db files nisplus nis dnshosts: ...
- Linux显示内存状态
Linux显示内存状态 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ free total used free shared buffers cached M ...
- 芝麻软件: Python爬虫进阶之爬虫框架概述
综述 爬虫入门之后,我们有两条路可以走. 一个是继续深入学习,以及关于设计模式的一些知识,强化Python相关知识,自己动手造轮子,继续为自己的爬虫增加分布式,多线程等功能扩展.另一条路便是学习一些优 ...
- 自定义方法实现ArrayList排序
package cn.edu.nwpu.java; import java.util.ArrayList; import java.util.Collection; import com.sun.xm ...
- pat1021-1030
1021求树的直径网上一搜就有,但是我不太理解 只需要一共求两次的dfs的论调,好吧我收回这句话,好想脑补了下,第一次dfs有多个最长点,只需要搜一个就行QAQ.这么看来我写麻烦了 #include& ...
- 实例 find
2011/09/08 12:00 时间开始找一天內的,会列出 2011/09/07 12:00 ~ 2011/09/08 12:00 时间內的文件3天前被改动过的文件 (前第三天以前 → 2011/0 ...