三.Windows I/O模型之事件选择(WSAEventSelect )模型
1.事件选择模型:和异步选择模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知。对于异步选择模型采用的网络事件来说,它们均可原封不动地移植到事件选择模型。事件选择模型和异步选择模型最主要的差别在于网络事件会投递至一个事件对象句柄,而非投递至一个窗口例程。
2.创建事件对象:事件选择模型要求应用程序针对打算使用事件选择模型的每一个套接字,首先创建一个事件对象。创建方法是调用WSACreateEvent函数,它的定义如下:WSAEVENT WSACreateEvent(void);
3.绑定事件对象与套接字:
int WSAEventSelect(
SOCKET s,
WSAEvent hEventObject,
long lNetworkEvents//网络事件,就是异步选择中的网络事件,用法完全相同
);
对于事件来说,他有两种类型,自动事件和人工事件。有两种状态,未触发状态和触发状态。使用WSACreateEvent函数创建的事件默认为人工事件且处于未触发状态。随着网络事件触发了与一个套接字关联在一起的事件对象,工作状态便会从未触发状态转变成触发状态。由于事件对象是在一种人工重设模式中创建的,所以在完成了一个I/O请求的处理之后,我们的应用程序需要负责将工作
状态触发状态更改未触发状态。
4.重置事件为未触发状态:
BOOL WSAResetEvent(WSAEVENT hEvent);
该函数的功能就是把时间从触发状态重置为未触发状态
5.关闭事件对象,释放其所占用的内核资源:
BOOL WSACloseEvent(WSAEVENT hEvent);
6.监视事件对象的状态:
DWORD WSAWaitForMultipleEvents(
DWORD cEvents;//事件对象数组中事件的数目
const WSAEVENT FAR* lphEvents,//事件对象数组
BOOL fWaitAll,//该参数指明了是否要等到所有事件对象变为触发状态函数才返回
DWORD dwTimeout,//超时,毫秒为单位超过规定的时间,函数就会立即返回,即使由fWaitAll参数规定的条件尚未满足也如此
BOOL fAlertable//忽略,置为FALSE
);
参数:
要注意的是,WSAWaitForMultipleEvents只能支持由WSA_MAXIMUM_WAIT_EVENTS对象规定的一个最大值,在此定义成6 4个。因此,针对发出WSAWaitForMultipleEvents调用的每个线程,该I/O模型一次最多都只能支持6 4个套接字。假如想让这个模型同时管理不止64个套接字,必须创建额外的工作者线程,以便等待更多的事件对象。fWaitAll 参数指定了指明了是否要等到所有事件对象变为触发状态函数才返回。若设为TRUE,那么只有等lphEvents数组内包含的所有事件对象都已进入触发状态,函数才会返回;但若设为FALSE,任何一个事件对象进入触发状态,函数就会返回。就后一种情况来说,返回值指出了到底是哪个事件对象造成了函数的返回。通常,应用程序应将该参数设为FALSE,通常,dwTimeout被置为0.
一次只为一个套接字事件提供服务
函数解释:
一个套接字同一个事件对象句柄关联在一起后,应用程序便可开始I/O处理;方法是等待网络事件触发事件对象句柄的工作状态。WSAWaitForMultipleEvents函数的设计宗旨便是用来等待一个或多个事件对象句柄,并在事先指定的一个或所有事件对象进入触发状态后,
或在超过了一个规定的时间周期后,立即返回。
7.确定网络事件发生的套接字:若WSAWaitForMultipleEvents收到一个事件对象的网络事件通知,便会返回一个值,指出造成函数返回的事件对象。这样一来,我们的应用程序便可引用事件数组中已传信的事件,并检索与那个事件对应的套接字,判断到底是在哪个套接字上,发生了什么网络事件类型。对事件数组中的事件进行引用时,应该用WSAWaitForMultipleEvents的返回值,减去预定义值WSA_WAIT_EVENT_0,得到具体的引用值(即索引位置)。
Index=WSAWaitForMultipleEvents(...);
myEvent=EventArray[Index-WSA_WAIT_EVENT_0];
7.调查发生的网络事件类型:
int WSAEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObjects,//参数可选,对应于打算重设的事件对象,即设置事件为未触发状态。和WSAtResetEvent函数功能相同
LPWSANETWORKEVENTS lpNetworkEvents//用来接受发生的网络事件类型以及可能出现的任何错误代码
);
该函数中的第四个参数用来接收发生的网络事件类型
8.WSANETWORKEVENTS结构:
tydef struct _WSANETWORKEVENTS
{
long lNetworkEvents;//网络事件类型
long iErrorCode[FD_MAX_EVENTS];//错误代码
}WSANETWORKEVENTS,FAR* LPWSANETWORKEVENTS;
iErrorCode参数指定的是一个错误代码数组,同lNetworkEvents中的事件关联在一起。iErrorCode针对每个网络事件类型,都存在着一个特殊的事件索引,名字与事件类型的名字类似,只是要在事件名字后面添加一个“ _BIT”后缀字串即可.
示例代码:
SOCKET Socket[WSA_MAXIMUM_WAIT_EVENTS];//
WSAEVENT event[WSA_MAXIMUM_WAIT_EVENTS];
SOCKET accept,listen;
DWORD eventTotal=;
DWORD index; //创建套接字
listen=socket(...); //绑定本地地址
bind(...); //创建事件对象
WSAEVENT newEvent;
newEvent=WSACreateEvent(); //注册网络事件
WSAEventSelect(listen,newEvent,FD_ACCEPT|FD_CLOSE); Socket[eventTotal]=listen;
event[eventTotal]=newEventl;
eventTotal++; while()
{
//等待事件触发状态
index=WSAWaitForMultipleEvents(eventTotal,event,FALSE,WSA_INFINITE,FALSE); //查看发生的网络事件类型,确定发生网络事件的套接字
WSANETWORKEVENTS networkEvents;
WSAEnumNetworkEvents(Socket[index-WSA_WAIT_EVENT_0],event[index-WSA_WAIT_EVENT_0],&networkEvents); //确定发生的网络事件类型
if(networkEvents.lNetworkEvents&FD_ACCEPT)
{
if(networkEvents.iErrorCode[FD_ACCEPT_BIT]!=)
{
printf("FD_ACCEPT failed with error %d\n",networkEvents.iErrorCode[FD_ACCEPT_BIT]);
break;
} //FD_ACCEPT事件发生后,则进行后续处理
accept=accept(Socket[index_WSA_WAIT_EVENT_0],NULL,NULL); //查看事件对象的数目
if(eventTotal>WSA_MAXIMUM_WAIT_EVENTS)
{
printf("too many connections\n");
closesocket(accept);
break;
} //再次创建事件,再次进行上述操作,进行循环
newEvent=WSACreateEvent(); WSAEventSelect(listen, newEvent, FD_READ|FD_WRITE | FD_CLOSE); event[eventTotal]=newEvent;
Socket[eventTotal]=accept;
eventTotal++;
printf("socket %d connected\n",accept);
} //FD_READ事件的处理
//雷同于FD_ACCEPT网络事件的处理
if(networkEvents.lNetworkEvents&FD_READ)
{
if(networkEvents.iErrorCode[FD_READ_BIT]!=)
{
printf("FD_READ failed with error %d\n",networkEvents.iErrorCode[FD_READ_BIT]);
break;
}
//读取数据
recv(Socket[index-WSA_WAIT_EVENT_0],buf,sizeof(buf),);
} //接下来其他网络事件的处理同上,但是需要注意一点,事件选择模型是基于窗口程序的,并且需要消息发送,只是这部分代码为给出而已 }
三.Windows I/O模型之事件选择(WSAEventSelect )模型的更多相关文章
- windows下的IO模型之事件选择(WSAEventSelect)模型
异步选择模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知.对于异步选择模型采用的网络事件来说,它们均可原封不动地移植到事件选择模型.事件选择模型和异步选择模型最主要的 ...
- 二.Windows I/O模型之异步选择(WSAAsyncSelect)模型
1.基于windows消息为基础的网络事件io模型.因此我们必须要在窗口程序中使用该模型.该模型中的核心是调用WSAAsyncSelect函数实现异步I/O. 2.WSAAsyncSelect函数:注 ...
- WinSock WSAEventSelect 模型总结
前言 本文配套代码:https://github.com/TTGuoying/WSAEventSelect-model 由于篇幅原因,本文假设你已经熟悉了利用Socket进行TCP/IP编程的基本原理 ...
- windows socket网络编程--事件选择模型
目录 事件选择模型概述 API详解 工作原理 代码实现 事件选择模型概述 Winsock提供了另一种有用的异步事件通知I/O模型--WSAEventSelect模型.这个模型与WSAAsyncSele ...
- windows下的IO模型之异步选择(WSAAsyncSelect)模型
异步选择(WSAAsyncSelect)模型是一个有用的异步I/O 模型.其核心函数是WSAAsyncSelect,该函数是非阻塞的 (关于异步io的理解详情可以看:http://www.cnblog ...
- 一.Windows I/O模型之选择(select)模型
1.选择(select)模型:选择模型:通过一个fd_set集合管理套接字,在满足套接字需求后,通知套接字.让套接字进行工作.避免套接字进入阻塞模式,进行无谓的等待.选择模型的核心的FD_SET集合和 ...
- Linux下套接字具体解释(三)----几种套接字I/O模型
參考: 网络编程–IO模型演示样例 几种server端IO模型的简介及实现 背景知识 堵塞和非堵塞 对于一个套接字的 I/O通信,它会涉及到两个系统对象.一个是调用这个IO的进程或者线程,还有一个就是 ...
- Windows下Qt开发环境:OpenGL导入3DMax模型(.3DS)
参考:http://blog.csdn.net/cq361106306/article/details/41876541 效果: 源代码: 解释: CLoad3DS.h为加载3DMax模型的头文件,C ...
- c++ 网络编程(十) LINUX/windows 异步通知I/O模型与重叠I/O模型 附带示例代码
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9662931.html 一.异步IO模型(asynchronous IO) (1)什么是异步I/ ...
随机推荐
- matlab学习菜单控件的基本用法
编辑菜单项 上下文菜单,即弹出菜单 然后添加一个坐标系 添加回调函数 %余弦曲线x=0:0.01:2*pi;y=cos(x);axes(handles.axes1);%将坐标系的值写进h=plot(x ...
- HTTP数据包详解
无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了Web应用程序的内部工作. 本文将对HTTP协议进行详细的实例讲解,内容较多,希望大家耐心看. 阅读目录 ...
- matlab 读取输入数组
In an assignment A(I) = B, the number of elements in B and I must be the same MATLAB:index_assign_el ...
- Linux基础:uniq命令总结
本文只总结一些常用的用法,更详细的说明见man uniq和 uniq --help. uniq命令 uniq命令主要用于去重. 需要注意的是,不相邻的行不算重复值. 语法格式 Usage: uniq ...
- 33.bulk json格式的理解
bulk json格式的理解 一.常规格式 按常规理解,bulk中json格式可以是以下方式 [{ "action": { }, "data": { } }] ...
- JavaScript响应式轮播图插件–Flickity
简介 flickity是一款自适应手机触屏滑动插件,它的API参数很丰富,包括对齐方式.循环滚动.自动播放.是否支持拖动.是否开启分页.是否自适应窗口等. 在线演示及下载 演示地址 下载页面 使用方法 ...
- 一种脱离VC编程软件的方法学习C/C++编程(搭建EditPlus实现在文本编辑框中执行.c文件
网上下载一个EditPlus记事本安装好后就可以按照下面步骤进行搭建环境了: 一.工具(Tools)→配置用户工具(Configure UserTools...),[添加工具](Add Tool> ...
- Music in Car
Music in Car time limit per test 1 second memory limit per test 256 megabytes Sasha reaches the work ...
- dubbo-源码阅读之dubboSpi实现原理
dubboSPI实现思想跟javaspi的思想差不多javaspi是ServiceLoad 而dubbo自己写的是ExtensionLoader SPI接口定义 @Documented @Retent ...
- 转载 - KMP算法祥解
出处:http://www.cppblog.com/oosky/archive/2006/07/06/9486.html KMP字符串模式匹配详解 来自CSDN A_B_C_ABC 网友 KM ...