WSAAsyncSelect模型
==============================================
█ 异步选择(WSAAsyncSelect)模型是一个有用的异步 I/O 模型。利用这个模型,应用程序可在一个套接字上,
接收以 Windows 消息为基础的网络事件通知。具体的做法是在建好一个套接字后,调用WSAAsyncSelect函数。
该模型的核心即是WSAAsyncSelect函数。
█ 要想使用 WSAAsyncSelect 模型,在应用程序中,首先必须用CreateWindow函数创建一个窗口,再为该窗口提供一个窗口例程函数(WinProc)。
█ 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上,接收到有关连接、发送、接收以及套接字关闭这一系列网络事件的通知。
█ 注意 ①:
多个事件务必在套接字上一次注册!
另外还要注意的是,一旦在某个套接字上允许了事件通知,那么以后除非明确调用closesocket命令,
或者由应用程序针对那个套接字调用了WSAAsyncSelect,从而更改了注册的网络事件类型,否则的话,
事件通知会永远有效!若将lEvent参数设为0,效果相当于停止在套接字上进行的所有网络事件通知。
█ 注意 ②:
若应用程序针对一个套接字调用了WSAAsyncSelect,那么套接字的模式会从“锁定”变成“非锁定”。
这样一来,如果调用了像WSARecv这样的Winsock函数,但当时却并没有数据可用,那么必然会造成调用的失败,并返回WSAEWOULDBLOCK错误。
为防止这一点,应用程序应依赖于由WSAAsyncSelect的uMsg参数指定的用户自定义窗口消息,来判断网络事件类型何时在套接字上发生;而不应盲目地进行调用。
FD_READ 应用程序想要接收有关是否可读的通知,以便读入数据
FD_WRITE 应用程序想要接收有关是否可写的通知,以便写入数据
FD_ACCEPT 应用程序想接收与进入连接有关的通知
FD_CONNECT 应用程序想接收与一次连接完成的通知
FD_CLOSE 应用程序想接收与套接字关闭的通知
█ 应用程序在一个套接字上成功调用了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的低字部分。
█ 注意 ③:应用程序如何对 FD_WRITE 事件通知进行处理。
只有在三种条件下,才会发出 FD_WRITE 通知:
■ 使用 connect 或 WSAConnect,一个套接字首次建立了连接。
■ 使用 accept 或 WSAAccept,套接字被接受以后。
■ 若 send、WSASend、sendto 或 WSASendTo 操作失败,返回了 WSAEWOULDBLOCK 错误,而且缓冲区的空间变得可用。
因此,作为一个应用程序,自收到首条 FD_WRITE 消息开始,便应认为自己必然能在一个套接字上发出数据,
直至一个send、WSASend、sendto 或 WSASendTo 返回套接字错误 WSAEWOULDBLOCK。
经过了这样的失败以后,要再用另一条 FD_WRITE 通知应用程序再次发送数据。
WSAAsyncSelect模型的更多相关文章
- 问题解决——WSAAsyncSelect模型 不触发 FD_CLOSE
==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...
- winsock编程WSAAsyncSelect模型
winsock编程WSAAsyncSelect模型 WSAAsyncSelect模型也称异步选择模型,其核心函数是WSAAsyncSelect.它可以用来在一个socket上接收以windows消息为 ...
- WSAAsyncSelect模型触发不了FD_Close消息?
原帖链接: http://bbs.csdn.net/topics/330164174 楼主: Server用WSAAsyncSelect模型,Client关闭程序时(不进行shutdown与close ...
- WSAAsyncSelect 模型
WSAAsyncSelect模型是winsock编程模型的一种,它提供了socket异步编程的方便,其实现是基于Windows消息机制的,最主要的就是下面这个函数: int PASCAL FAR WS ...
- 基于WSAAsyncSelect模型的两台计算机之间的通信
任务目标 编写Win32程序模拟实现基于WSAAsyncSelect模型的两台计算机之间的通信,要求编程实现服务器端与客户端之间双向数据传递.客户端向服务器端发送"请输出从1到1000内所有 ...
- Win32 API编程:网络编程在设置WSAAsyncSelect模型后connect的返回值问题
通过WSAAsyncSelect()可以设置非阻塞异步套接字 ::WSAAsyncSelect(s, hDlg, WM_SOCKET, FD_CONNECT | FD_CLOSE | FD_WRITE ...
- 二.Windows I/O模型之异步选择(WSAAsyncSelect)模型
1.基于windows消息为基础的网络事件io模型.因此我们必须要在窗口程序中使用该模型.该模型中的核心是调用WSAAsyncSelect函数实现异步I/O. 2.WSAAsyncSelect函数:注 ...
- Socket WSAAsyncSelect模型
::WSAAsyncSelect(sListen, hWnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE); 自定义 WM_SOCKET消息 #include "../co ...
- WSAAsyncSelect模型中,FD_WRITE事件什么时候触发?
当一个套接字连接被建立上时(包括客户端的connect(),connectex()等和服务器端的accept接收到后创建的新套接字),这时会触发FD_WRITE,以后就可以用send(),WSASen ...
随机推荐
- height为100%的问题
问题描述 很多同学,对于设置div 的高度为100%时,有疑惑. 设置div 的高度为100%,意思是此 div 的高度 铺满父元素. 那么 怎么使 div 铺满浏览器屏幕? 代码 <!DOCT ...
- 读书笔记之 - javascript 设计模式 - 工厂模式
一个类或者对象中,往往会包含别的对象.在创建这种对象的时候,你可能习惯于使用常规方式,即用 new 关键字和类构造函数. 这会导致相关的俩个类之间产生依赖. 工厂模式,就是消除这俩个类之间的依赖性的一 ...
- .net日志专用
一个简单的.net写日志方法 - 可能的改进点 昨天有个朋友在评论的时候问我如下代码在web开发中有什么问题 public void Log(string msg) { System.IO.File. ...
- Asp.net Mvc HTTP 404。
asp.net mvc 设置完起始页的时候会出现以下Error 此错误的原因是在MVC中设置完起始页 会改变 的 值 从而使服务器找不到 相对应的路径 解决方案: 通过 路由设置,解决web ...
- RM-Linux驱动--Watch Dog Timer(看门狗)驱动分析
from:http://blog.csdn.net/geekcome/article/details/6595265 硬件平台:FL2440 内核版本:2.6.28 主机平台:Ubuntu 11,04 ...
- html doctype 作用
文档模式主要有以下两个作用: 1.告诉浏览器使用什么样的html或xhtml规范来解析html文档 2.对浏览器的渲染模式产生影响:不同的渲染模式会影响到浏览器对于 CSS 代码甚至 JavaScri ...
- Presto: 可以处理PB级别数据的分布式SQL查询引擎
2012年秋季Facebook启动了Presto,Presto的目的是在几百PB级别数据量上面进行准实时分析.在摒弃了一些外部项目以后,Facebook准备开发他们自己的分布式查询引擎.Presto的 ...
- 标签form表单里的属性简单介绍了一下
<form id="form1" name="form1" method="post" action=""> ...
- 不用第三个变量,将a,b两个值互换,会出现什么样的异常?
1 相互加减 a = a + b; b = a - b; a = a - b; 但会出现异常 如果a+b超过a类型的范围,俗称溢出异常. 2 指针操作交换地址 3 异或操作 转自网络搜索的答案
- phpwind9.0 顶部和底部版权信息永久性修改
过了pw头部和底部版权修改方法,但是每次升级程序后版权又变成了默认的了,还得重新修改,其实有个方法可以永久性修改,底部和顶部随着主题走. pw9全局主题位于/themes/site/目录下, 前面文 ...