网络程序设计——重叠I/O模型
创始人
2024-02-21 01:55:04
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缓冲区到应用程序缓冲区的拷贝。

如有错误,敬请指正。

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

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...