三.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/ ...
随机推荐
- python 生成HTmL报告页面 V1.2
上代码 # -*- coding=utf-8 -*- import time,os #数据部分 func_dict={"funcname":"模块1",} fu ...
- php第八节课
加载 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...
- C++ 资源大全中文版
标准库 C++标准库,包括了STL容器,算法和函数等. C++ Standard Library:是一系列类和函数的集合,使用核心语言编写,也是C++ISO自身标准的一部分. Standard Tem ...
- python 对图片做垂直投影
Python 对图片做垂直投影 本文利用opencv对图片进行垂直投影,做出垂直投影图,大体思路:打开图片,灰度化,二值化,按列进行统计,新建一个大小和原图一样的图片,按列进行填充: cv2.cv.G ...
- Java基础学习总结(39)——Log4j 1使用教程
1. 配置文件 Log4J配置文件的基本格式如下: #配置根Logger log4j.rootLogger = [ level ] , appenderName1 , appenderN ...
- netty helloWord (一)
什么是nettty netty是基于javaNio模型的网络编程框架.很多框架底层也是用netty实现的 比如dubbo 与NIO的区别 1.简化了API的使用.基于事件驱动.只需要在对应的事件写相应 ...
- 百度之星2014初赛 - 1002 - Grids
先上题目: Grids Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tota ...
- 0419MySQL ORDER BY的实现分析
转自:http://www.2cto.com/database/201202/120001.html 简朝阳 总的来说,在 MySQL 中的ORDER BY有两种排序实现方式,一种是利用有序索引获取有 ...
- DJANGO里让用户自助修改邮箱地址
因为在部署过程中会涉及用户邮件发送,如果有的同事不愿意收到太多邮件,则可以自己定义为不存在的邮箱. 我们在注册的时候,也不会写用户邮箱地址,那么他们也可以在这里自己更改. changeemail.ht ...
- HDU 5187
超简单的公式题(2^n-2).不过,要过可不容易,因为会爆64位,所以,可以使用快速乘法. #include <iostream> #include <cstdio> #inc ...