网络程序设计——重叠I/O模型
创始人
2024-02-20 21:31:20
0

目录

1、重叠I/O

(1)概念

(2)重叠数据结构WSAOVERLAPPED  

2、重叠I/O的相关函数

(1)套接字创建

(2)发送数据函数

(3)两种获取传输数据数量的方法

3、 重叠I/O模型的编程框架

(1)使用事件通知方式进行重叠I/O的编程框架

 (2)使用完成例程方式进行重叠I/O的编程框架

(3)以面向连接额的数据接收为例

4、重叠I/O模型评价

1、重叠I/O

(1)概念

  •        重叠I/O模型是以Windows重叠I/O机制为基础的套接字I/O模型。Windows重叠I/O本来是一种文件操作技术。在传统文件操作中,文件的读写函数都是以阻塞模式工作的,当文件很大或磁盘读写速度较低时,程序运行就会长时间阻塞在文件的读写操作上,直到读写完成才返回。这样将浪费很多时间,导致程序性能下降。为了解决这个问题,Windows引进了重叠I/O的概念。能同时以多个线程处理多个I/O。
  •       在重叠I/O下,应用程序在调用文件读写函数后函数会立即返回,而不必等待操作结束,文件读写的同时应用程序可以执行其他操作,这就是所谓的异步I/O操作。如果让应用程序连续进行多个文件读写函数的调用,使得系统同时执行多个文件的读写操作,就成为所谓的重叠I/O操作
  •         WinSock的重叠I/O模型就是以重叠I/O机制为基础开发的。从WinSock2开始,重叠I/O模型便被引入到WinSock的扩展套接字函数中,这些扩展函数的格式不再与BSD套接字函数兼容,函数名均以WSA开头,比如recv()函数和send()函数的Windows扩展版分别为WSARecv()和WSASend()。应用程序要使用重叠I/O模型,就必须使用WinSock扩展套接字函数。

(2)重叠数据结构WSAOVERLAPPED  

typedef struct _WSAOVERLAPPED{
ULONG_PTR Interal; //底层操作系统使用
ULONG_PTR InteralHigh; //底层操作系统使用
union{struct{DWORD offset; //套接字是忽略,文件操作使用。DWORD offsetHigh; //忽略};
PVOID Pointer; //忽略
};
HANDLE hEvent;//允许应用程序为这个操作关联一个事件对象句柄
}WSAOVERLAPPED, *LPWSAOVERLAPPED;
  •        重叠I/O的事件通知方法需要Windows事件对象关联到WSAOVERLAPPED结构。当I/O完成时,会将WSAOVERLAPPED结构中的hEvents置为有信号状态。
  •       通过调用WSAWaitForMultipleEvents()来等待I/O完成的通知,在得到通知信号后,就可以调用WSAGetOverlappedResult()来查询I/O操作的结果,并进行相关处理。WSAOVERLAPPED结构在重叠I/O请求初始化及其后续的完成之间提供一个沟通或通信机制。

2、重叠I/O的相关函数

(1)套接字创建

SOCKET WSASocket{int af, int type, int protocol,
LPWSAPROTOCOL_INFO lpProtocolInfo,//指定新套接字的特性
GROUP g, //保留
DWORD dwFlags//在重叠I/O模型中,需要设置为WSA_FLAG_OVERLAPPED。
};

(2)发送数据函数

int WSASend{SOCKET s,
LPWSABUF lpBuffers,//指向WSABUF结构数组的指针
DWORD dwBufferCount,//记录lpBuffers数组中WSABUF结构的数目
LPDWORD lpNumberOfBytesSent, //返回指向发送的字节数的指针
DWORD dwFlags, //标志
LPWSAOVERLAPPED lpOverlapped, //指向重叠结构的指针
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
//指向发送操作完成后调用的完成例程};

       如果重叠操作立即完成,则返回0;如果重叠操作被成功初始化,并且稍后完成,则返回WSA_IO_PENDING。

(3)两种获取传输数据数量的方法

  • 1)如果指定了完成例程,通过cbTransferred参数获取
  • 2)通过WSAGetOverlappedResult()的参数lpcbTransferred获取。

3、 重叠I/O模型的编程框架

WinSock可以使用事件通知和完成例程两种方式来实现重叠I/O的操作。

(1)使用事件通知方式进行重叠I/O的编程框架

  • 套接字初始化,设置为重叠I/O模式;
  • 创建套接字网络事件对应的用户事件对象;
  • 初始化重叠结构,为套接字管理事件对象;
  • 异步接收数据,无论能否接收到数据,都会直接返回;
  • 调用WSAWaitForMultipleEvents(),在所有事件对象上等待,只要有一个事件对象变为授信状态,则返回;
  • 调用WSAGetOverlappedResult(),获取套接字上的重叠操作状态,并保存到重叠结构中;
  • 根据重置事件的状态进行处理;
  • 重置已授信的事件对象、重叠结构、标志位和缓冲区;
  • 回到步骤4。

 (2)使用完成例程方式进行重叠I/O的编程框架

      对于网络重叠I/O操作,等待I/O操作结束的另一种方法是使用完成例程。异步的发送和接收接口函数的参数中的最后一个参数lpCompletionROUTINE就是用来指向完成例程的指针。若指定此参数,hEvent参数将被忽略,上下文信息将传送给完成例程函数。

①完成例程函数原型

void CALLBACK CompletionROUTINE{
DWORD dwError, //指定lpOverlapped参数中表示的重叠操作的完成状态
DWORD cbTransferred, //传送完成的数据数量
LPWSAOVERLAPPED lpOverlapped, //指定重叠结构
DWORD dwFlags  //指定操作结束时的标记,通常设置为0
};

(3)以面向连接额的数据接收为例

  • 套接字初始化,设置为重叠I/O模式;
  • 初始化重叠结构;
  • 异步传输数据,将重叠结构作为输入参数,并指定一个完成例程对应于数据传输后的处理;
  • 调用WSAWaitForMultipleEvents()或SleepEx(),将自己的线程设置为一种可警告等待状态,等待一个重叠I/O请求完成,重叠请求完成后,完成例程会自动执行,在完成例程内,可随一个完成例程一起投递另一个重叠I/O操作;
  • 回到步骤3。

4、重叠I/O模型评价

  • 应用程序中的I/O操作<-->重叠结构<-->事件
  • 使应用程序能达到更佳的系统性能
  • 减少了一次从I/O缓冲区到应用程序缓冲区的拷贝。

如有错误,敬请指正。

您的收藏与点赞都是对我最大的鼓励和支持!

相关内容

热门资讯

流感、带状疱疹、HPV疫苗优惠... 记者从市卫健委获悉, 按照黑龙江省疾病预防控制局统一部署,为切实守护好市民健康,哈尔滨市卫生健康委员...
特朗普起诉BBC诽谤。(POL... 特朗普起诉BBC诽谤,寻求向BBC索赔至少50亿美元。(Politico)
国家外汇管理局:稳步扩大外汇领... 近日,国家外汇管理局党组书记、局长朱鹤新主持召开党组(扩大)会议,传达学习中央经济工作会议精神,结合...
【专家称明年财政政策“工具箱”... 【专家称明年财政政策“工具箱”有望进一步扩容】展望2026年,财政政策在制定与执行的过程中将紧密结合...
2026年重点推动生育保险发展... 12月13日,全国医疗保障工作会议上释放的信息提到,2026年要重点推动生育保险发展,“力争做到让孕...
明年财政政策“工具箱”有望进一... 回顾2025年,更加积极的财政政策在保障国家重大战略实施,扩内需、稳增长、惠民生方面取得积极成效。展...
住建部部长倪虹:优化保障性住房... 住房和城乡建设部部长倪虹在人民日报发表署名文章《推动房地产高质量发展(学习贯彻党的二十届四中全会精神...
住建部部长倪虹人民日报发文!改... 12月16日,住房和城乡建设部部长倪虹在人民日报发表署名文章《推动房地产高质量发展》。 文章提到,改...
“开库”政策放宽!深圳安居房惠... 深圳商报首席记者 李秀瑜 “双十二”大促热潮还未退,深圳安居房配售也送上民生礼包。记者从市住房建设局...
住建部部长倪虹:改革完善房地产... 人民财讯12月16日电,住房城乡建设部部长倪虹在《人民日报》发表署名文章《推动房地产高质量发展(学习...