1.基于windows消息为基础的网络事件io模型。因此我们必须要在窗口程序中使用该模型。该模型中的核心是调用WSAAsyncSelect函数实现异步I/O。

2.WSAAsyncSelect函数:注册网络事件函数
int WSAAsyncSelect(
    SOCKET s,//
    HWND hWnd,//
    unsigned int wMsg,//注意,该消息值应该大于WM_USER(1024)
    long lEvent,//网络事件
    );
若应用程序针对一个套接字调用了WSAAsyncSelect,那么套接字的模式会从阻塞自动变成非阻塞,这样一来,假如调用了像WSARecv这样的Winsock I/O函数,但当时却并没有数据可用,那么必然会造成调用的失败,并返回WSAEWOULDBLOCK错误。为防止这一点,应用程序应依赖于由WSAAsyncSelect的uMsg参数指定的用户自定义窗口消息,来判断网络事件类型何时在套接字上发生;而不应盲目地进行调用。

3.网络事件:
(1)FD_READ:读数据
(2)FD_WRITE:写数据
(3)FD_ACCEPT:接收连接
(4)FD_CONNECT:连接
(5)FD_CLOSE:关闭
各个事件可以进行或运算。特别要注意的是,多个事件务必在套接字上一次注册!另外还要注意的是,一旦在某个套接字上允许了事件通知,那么以后除非明确调用closesocket命令,或者由应用程序针对那个套接字调用了WSAAsyncSelect,从而更改了注册套接字的网络事件类型,否则的话,事件通知会永远有效!若将lEvent参数设为0,效果相当于停止在套接字上进行的所有网络事件通知。

4.在异步选择模型中,还需要自定义窗口消息处理函数。来对各种网络事件进行处理。该函数定义和win32窗口中的窗口消息处理函数相同。原型如下:
LRESULT CALLBACK WindowProc(
    HWND hWnd,//
    UINT uMsg,//
    WPARAM wParam,//
    LPARAM lParam
    )
参数lParam的低字(低位字)指定了已经发生的网络事件,而lParam的高字(高位字)包含了可能出现的任何错误代码。
网络事件消息抵达一个窗口例程后,应用程序首先应检查lParam的高字位,以判断是否在套接字上发生了一个网络错误。这里有一个特殊的宏WSAGETSELECTERROR,可用它返回高字位包含的错误信息。若套接字上没有产生任何错误,接着便应判断到底是哪个网络事件发生。具体的做法便是读取lParam低字节的内容。此时可使用另一个特殊的宏:WSAGETSELECTEVENT,用它返回lParam低字节的内容。

5.最后一个特别有价值的问题是应用程序如何对FD_WRITE事件进行处理。只有在三
种条件下,才会发出FD_WRITE通知:
(1)使用connect或WSAConnect,一个套接字首次建立了连接。
(2)使用accept或WSAAccept,套接字被接受以后。
(3)若send、WSASend、sendto或WSASendto操作失败,返回了WSAWOULDBLOCK错误,而且缓冲区的空间变得可用
因此,作为一个应用程序,自收到首条FD_WRITE消息开始,便应认为自己必然能在一个套接字上发出数据,直至一个send、WSASend、sendto或WSASendto返回套接字错误WSAWOULDBLOCK。经过了这样的失败以后,要再用另一条FD_WRITE通知应用程序再次发送数据。

示例代码:

 #define WM_SOCKET WM_USER+1
#include<Windows.h> int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
//初始化
SOCKET listen;
HWND window;
window=CreateWindow(...);//这一步并没有多大必要 WSAStartUp(...);
listen=socket(...); //绑定地址
... //注册网络事件
WSAAsyncSelect(listen,window,WM_SOCKET,FD_ACCEPT|FD_CLOSE); //转发消息
SendMessage(...); } //窗口消息处理函数
BOOL CALLBACK ServerWinProc(HWND hWnd,WORD wMsg,WPARAM wParam,LPARAM lParam)
{
SOCKET Accept; case WM_PAINT:
..
break;
case WM_SOCKET:
if(WSAGETSELECTERROR(lParam))
{
...
closesocket(Accept);
break;
}
if(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
...
break;
case FD_CLOSE:
...
break;
case ...
}
}

二.Windows I/O模型之异步选择(WSAAsyncSelect)模型的更多相关文章

  1. 三.Windows I/O模型之事件选择(WSAEventSelect )模型

    1.事件选择模型:和异步选择模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知.对于异步选择模型采用的网络事件来说,它们均可原封不动地移植到事件选择模型.事件选择模型和 ...

  2. windows下的IO模型之异步选择(WSAAsyncSelect)模型

    异步选择(WSAAsyncSelect)模型是一个有用的异步I/O 模型.其核心函数是WSAAsyncSelect,该函数是非阻塞的 (关于异步io的理解详情可以看:http://www.cnblog ...

  3. socket 异步选择 WSAAsyncSelect 用法

    WSAAsyncSelect 实现给异步socket给了另一种实现方式,就是通过窗口消息的方式来提醒对socket接收还是发送 msdn有非常全面的解释:https://msdn.microsoft. ...

  4. windows下的IO模型之事件选择(WSAEventSelect)模型

    异步选择模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知.对于异步选择模型采用的网络事件来说,它们均可原封不动地移植到事件选择模型.事件选择模型和异步选择模型最主要的 ...

  5. WinSock 异步I/O模型 转载

    如果你想在Windows平台上构建服务器应用,那么I/O模型是你必须考虑的.Windows操作系统提供了五种I/O模型,分别是: ■ 选择(select):■ 异步选择(WSAAsyncSelect) ...

  6. WinSock 异步I/O模型

    如果你想在Windows平台上构建服务器应用,那么I/O模型是你必须考虑的. Windows操作系统提供了五种I/O模型,分别是选择(select)模型,异步选择(WSAAsyncSelect)模型, ...

  7. Delphi最简化异步选择TCP服务器

    网上Delphi的Socket服务器优良代码,实在少见,索性写个简化的异步Socket服务器,虽然代码较少,但却该有的都有了,使用的是异步选择WSAAsyncSelect,减少了编写线程的繁琐.可能会 ...

  8. c++ 网络编程(十) LINUX/windows 异步通知I/O模型与重叠I/O模型 附带示例代码

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9662931.html 一.异步IO模型(asynchronous IO) (1)什么是异步I/ ...

  9. windows 异步通知I/O模型与重叠I/O模型

    一.异步IO模型(asynchronous IO) (1)什么是异步I/O 异步I/O(asynchronous I/O)由POSIX规范定义.演变成当前POSIX规范的各种早起标准所定义的实时函数中 ...

随机推荐

  1. 模拟登录新浪微博(Python)

    PC 登录新浪微博时, 在客户端用js预先对用户名.密码都进行了加密, 而且在POST之前会GET 一组参数,这也将作为POST_DATA 的一部分. 这样, 就不能用通常的那种简单方法来模拟POST ...

  2. MessageFormat.format()用法

    1.java.text.Format的继承结构如下   2.MessageFormat模式 FormatElement { ArgumentIndex }:是从0开始的入参位置索引 { Argumen ...

  3. eas之日期控件

    日期选择框能进行日期和时间的编辑,默认情况下只能进行日期选择“××××年××月××日”,可通过调用用函数setTimeEnabled(boolean)来设置是否也有时间编辑.对日期进行编辑时,可手工直 ...

  4. 线程同步、信号量、system v IPC

    一.线程同步 条件变量 什么是条件变量? 线程A等待某个条件成立,条件成立,线程A才继续向下执行.线程B的执行使条件成立,条件成立以后唤醒线程A,以继续执行.这个条件就是条件变量. pthread_c ...

  5. [USACO10DEC]宝箱Treasure Chest

    区间DP,但是卡空间. n2的就是f[i,j]=sum[i,j]-min(f[i+1][j],f[i][j-1])表示这个区间和减去对手取走的最多的. 但是空间是64MB,就很难受 发现一定是由大区间 ...

  6. SQLServer · BUG分析 · Agent 链接泄露分析(转载)

    背景 SQLServer Agent作为Windows服务提供给用户定期执行管理任务,这些任务被称为Job:考虑应用镜像的场景如何解决Job同步问题,AWS RDS的做法是不予理会,由用户维护Job, ...

  7. JavaScript对接百度地图api实现地图标点功能

    粗略的做了个地图标点功能 首先,去百度注册开发者账号,然后进入到百度地图开放平台 进入到控制台, 创建浏览器端应用,给个安全域名 然后去开发者文档JavaScript里面找地图展示文档,直接怼上去就行 ...

  8. UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组、ST表)

    连NOI Day1T1都不会做...看了题解都写不出来还要抄Claris的代码.. 题目链接: (luogu)https://www.luogu.org/problemnew/show/P1117 ( ...

  9. SIM卡中UCS2编码的三种格式(80,81,82)分析

    网上看到一篇比较好的说ucs2编码的文章,保存一下,原文地址: http://hi.baidu.com/youren4548/blog/item/fa08bd1bf61005058618bf1d.ht ...

  10. 【ACM】hdu_2020_绝对值排序_201308050929

    绝对值排序 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...