四.Windows I/O模型之重叠IO(overlapped)模型

1.适用于除Windows CE之外的各种Windows平台.在使用这个模型之前应该确保该系统安装了Winsock2.重叠模型的基本设计原理是使用一个重叠的数据结构,一次投递一个或多个Winsock I/O请求。在重叠模型中,收发数据使用WSA开头的函数。

2.WSA_FLAG_OVERLAPPED标志:要使用重叠模型。在创建套接字的时候,必须加上该标志。
SOCKET s=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
假如使用的是socket函数,而非WSASocket函数,那么会默认设置WSA_FLAG_OVERLAPPED标志。
若随一个WSAFLAGOVERLAPPED结构一起调用这些以WSA开头的函数(AcceptEx和TRansmiteFile函数例外),函数会立即完成并返回,无论套接字是否设为阻塞模式

3.重叠模型在网络事件完成后,可以有两种方式通知应用程序:事件通知和完成例程

3.事件通知:事件对象与WSAOVERLAPPED进行绑定实现网络事件完成后通过事件进行通知。

4.WSAOVERLAPPED结构:
typedef struct WSAOverlapped
{
    DWORD Internal;
    DOWRD InternalHigh;
    DWORD Offset;
    DWORD OffsetHigh;
    WSAEVENT hEvent;
}WSAOVERLAPPED,FAR* LPWSAOVERLAPPED;
此处,程序员可以使用的是最后一个参数hEvent,其余的不用管。通过该参数,重叠结构可以与事件对象进行绑定,以实现网络事件完成后,通过事件对象进行通知应用程序。事件对象通知方式是通过创建一个事件对象,把该对象赋值给重叠结构的hEvent参数即可实现绑定。在此再次提醒大家注意:WSAWaitForMultipleEvents函数一次最多只能等待64个事件对象。

5.WSAGetOverlappedResult函数:重叠请求完成后,接着需要调用WSAGetOverlappedResult(取得重叠结构)函数,判断那个重叠调用到底是成功,还是失败.
BOOL WSAGetOverlappedResult(
    SOCKET s,//套接字
    LPWSAOVERLAPPED lpOverlapped,//重叠结构
    LPDWORD lpcbTransfer,//对应一个DWORD(双字节)变量,一次重叠实际传输(接收或者发送)的字节数
    BOOL fWait,//参数用于决定函数是否应该等待一次重叠操作完成。
    LPWORD lpdwFlags
    );
重叠操作完成,函数返回TRUE,否则,返回FALSE。返回FALSE通常都是有一下几种情况造成的.
(1)重叠I/O操作仍处在未完成状态
(2)重叠操作已经完成,但含有错误
(3)重叠操作的完成状态不可判决,因为在提供给函数WSAGetOverlappedResult的一个或多个参数中,存在着错误。
失败后,由lpcbTransfer参数指向的值不会进行更新,而且我们的应用程序应调用WSAGetLastError函数

6.基于事件通知的重叠模型编程步骤如下:
(1) 创建一个套接字,绑定本机端口,在指定的端口上监听连接请求。
(2)接受连接请求。
(3)为接受的套接字新建一个WSAOVERLAPPED结构,并为该结构分配一个事件对象句柄。也将事件对象句柄分配给一个事件数组,以便稍后由函数WSAWaitForMultipleEvents使用。
(4)在套接字上投递一个异步WSARecv请求,指定参数为WSAOVERLAPPED结构。注意函数通常会以失败告终,返回SOCKETERROR错误状态WSAIOPENDING(I/O操作尚未完成)。
(5)使用步骤3)的事件数组,调用WSAWaitForMultipleEvents函数,并等待与重叠调用关联在一起的事件进入“已传信”状态(换言之,等待那个事件的“触发”)。
(6)WSAWaitForMultipleEvents函数完成后,针对事件数组,调用WSAResetEvent(重设事件)函数,从而重设事件对象,并对完成的重叠请求进行处理。
(7)使用WSAGetOverlappedResult函数,判断重叠调用的返回状态是什么。
(8)在套接字上投递另一个重叠WSARecv请求。
(9)重复步骤5 ) ~ 8 )。

示例代码:

 1 void main(void)
 2 {
 3     WSABUF databuf;
 4     DWORD eventTotal=0;
 5     WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];
 6     WSAOVERLAPPED acceptOverlapped;
 7     SOCKET listensock,acceptsock;
 8
 9
10     //初始化工作和一般socket通信相同
11     ...
12
13     //接收连接
14     acceptsock=accept(listensock,NULL,NULL);
15
16     //创建事件,绑定事件对象与重叠结构
17     eventArray[eventTotal]=WSACreateEvent();
18     ZeroMemory(&acceptOverlapped,sizeof(WSAOVERLAPPED));
19     acceptOverlapped.hEvent=eventArray[eventTotal];
20
21     //数据缓冲区初始化
22     databuf.len=DATA_BUFSIZE;
23     databuf.buf=buffer;
24
25     eventTotal++;
26
27     //投递接收请求
28     WSARecv(acceptsock,&databuf,1,&recvBytes,&flags,&acceptOverlapped,NULL);
29
30     while(1)
31     {
32         //监视事件对象状态
33         index=WSAWaitForMultipleEvents(eventTotal,eventArray,FALSE,WSA_INFINITE,FALSE);
34
35         //人工充值事件
36         WSAResetEvent(eventArray[eventTotal-WSA_WAIT_EVENT_0]);
37
38         //获取I/O操作的完成情况
39         WSAGetOverlappedResult(acceptsock,&acceptOverlapped,&bytesTransferred,FALSE,&flag);
40
41         if(bytesTransferred==0)
42         {
43             closesocket(acceptsock);
44             WSACloseEvent(eventArray[eventTotal-WSA_WAIT_EVENT_0]);
45             return;
46         }
47
48         //处理接收过来的数据
49         ...
50
51         //再再次发送一个WSARecv请求
52         flag=0;
53         ZeroMemory(&acceptOverlapped,sizeof(WSAOVERLAPPED));
54
55         databuf.LEN=DATA_BUFSIZE;
56         databuf.buf=buf;
57         WSARecv(acceptsock,&databuf,1,&recvbytes,&flag,&acceptOverlapped,NULL);
58     }
59
60 }

注意:对于接受客户端连接的函数,还有一个AcceptEx函数,不过这个函数太过麻烦且对性能的提升没有太大的作用,暂时不打算学习

接下来学习基于完成例程的重叠IO模型:

时间: 2024-11-06 07:20:05

四.Windows I/O模型之重叠IO(overlapped)模型的相关文章

Socket重叠IO

1.为什么到现在才弄懂这个 不知道这个Socket重叠IO这种模型是不是socket IO完成端口的基础,不过我感觉,学习一下这个再去学习socket IO完成端口是比较有好处的. 这个Scoket重叠IO我以前记得看过好几次,都没看懂.一部分原因是我没能静态心来写代码,还有更重要的原因就是,Socket重叠他们的结构体参数,还有传参数让人很难理解.下面我将对这些数据结构和参数进行一下讲解 2.初识WSARecv 函数 int WSARecv( SOCKET s,//要接收消息的socket L

【IOCP】 IOCP模型属于一种通讯模型- 较难

http://baike.baidu.com/link?url=e9vXkKd2aHp8VDr1XTURdwQB4K85r28IYjeMwRIyuaXtsrCsXHY1eohiFgsDXRYRlj6xEQoZFzH9dgKwla2n3q IOCP(I/O Completion Port),常称I/O完成端口. IOCP模型属于一种通讯模型,适用于(能控制并发执行的)高负载服务器的一个技术. 通俗一点说,就是用于高效处理很多很多的客户端进行数据交换的一个模型.或者可以说,就是能异步I/O操作的模型

windows的重叠IO模型

2019年5月29日 11:58 ? ? 同一线程内部向多个目标传输(或冲多个目标接收)数据引起的IO重叠现象称为"重叠IO".为了完成这项任务,调用IO的函数应立即返回,只有这样才能返送后续数据. 重叠IO收发数据最重要的前提条件就是异步IO. 在windows中重叠IO的重点并非IO本身,而是如何确认IO完成时的状态.因为不管输入还是输出,只要时非阻塞模式的,就要另外确认执行结果.确认执行结果前需要经过特殊的处理过程. ? ? 创建重叠IO套接字 #include <wins

重叠IO 模型

1. 重叠模型的优点 2. 重叠模型的基本原理 3. 关于重叠模型的基础知识 4. 重叠模型的实现步骤 5. 多客户端情况的注意事项 一.重叠模型的优点   1.可以运行在支持Winsock2的所有Windows平台 ,而不像完成端口只是支持NT系统. 2.比起阻塞.select.WSAAsyncSelect以及WSAEventSelect等模型,重叠I/O(Overlapped   I/O)模型使应用程序能达到更佳的系统性能.    因为它和这4种模型不同的是,使用重叠模型的应用程序通知缓冲区

四种主要网络IO虚拟化模型

本文主要为大家简要介绍VMware.Redhat.Citrix.Microsoft主要虚拟化厂商使用的4种主要的虚拟化IO模型 (emulation.para-virtualization.pass-through.SR-IOV).主要为大家穿针引线,信息量比较大,组织排 版有限,看官们将就点看着. 网络I/O不但是物理服务器最容易出现的瓶颈,也是现在虚拟化技术最大的硬伤.随着硬件虚拟化对网络I/O的支持,虚拟化的网络I/O模型也不断的 进化,虚拟化的I/O性能也不断提升.今天给大家分享VMwa

重叠io操作

第一章 一. 重叠模型的优点 1. 可以运行在支持Winsock2的所有Windows平台 ,而不像完成端口只是支持NT系统. 2. 比起阻塞.select.WSAAsyncSelect以及WSAEventSelect等模型,重叠I/O(Overlapped I/O)模型使应用程序能达到更佳的系统性能. 因为它和这4种模型不同的是,使用重叠模型的应用程序通知缓冲区收发系统直接使用数据,也就是说,如果应用程序投递了一个10KB大小的缓冲区来接收数据,且数据已经到达套接字,则该数据将直接被拷贝到投递

手把手教你玩转SOCKET模型之重叠I/O篇(上)

“身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人.我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬.” ----- 题记  By PiggyXP(小猪) 前   言   其实我首先应该道歉,因为7月份的时候曾信誓旦旦的说要写一套关于SOCKET所有模型的入门文章以及配套代码,不过没想到后天竟然被美女所迷出去度假了,刚刚回来不久......-_-b其实那些模型的配套代码我已经基本写完了,

手把手教你玩转SOCKET模型之重叠I/O篇(下)

四.     实现重叠模型的步骤 作 了这么多的准备工作,费了这么多的笔墨,我们终于可以开始着手编码了.其实慢慢的你就会明白,要想透析重叠结构的内部原理也许是要费点功夫,但是只是学会 如何来使用它,却是真的不难,唯一需要理清思路的地方就是和大量的客户端交互的情况下,我们得到事件通知以后,如何得知是哪一个重叠操作完成了,继而知道 究竟该对哪一个套接字进行处理,应该去哪个缓冲区中的取得数据,everything will be OK^_^. 下面我们配合代码,来一步步的讲解如何亲手完成一个重叠模型.

用完成例程(Completion Routine)实现的重叠I/O模型

/// 用完成例程(Completion Routine)实现的重叠I/O模型 /// 异步IO模型 /// 用完成例程来实现重叠I/O比用事件通知简单得多.在这个模型中,主线程只用不停的接受连接 /// 即可:辅助线程判断有没有新的客户端连接被建立,如果有,就为那个客户端套接字激活一个 /// 异步的WSARecv操作,然后调用SleepEx使线程处于一种可警告的等待状态,以使得I/O完成后 /// CompletionROUTINE可以被内核调用.如果辅助线程不调用SleepEx,则内核在完