ReadFileEx

ReadFileEx是一个Windows API函数。与ReadFile相似,只是它只能用于异步读取文件操作,异步操作完成后会调用指定的回调函数

BOOL ReadFileEx(
HANDLE                             hFile,                   //文件的句柄
LPVOID                             lpBuffer,                //用于接收数据的缓冲区
DWORD                              nNumberOfByteToRead,     //允许接收的最大字节数
LPOVERLAPPED                       lpOverlapped,            //一个OVERLAPPED结构的指针
LPOVERLAPPED_COMPLETION_ROUTINE    lpCompletionRoutine      //异步读取完成后调用的回调函数
);

参数

1、hFile

文件的句柄。这个参数可以是任何一个由带有FILE_FLAG_OVERLAPPED参数的CreateFile函数打开的句柄。这个句柄同时也需要有GENERIC_WRITE访问权限。

2、lpBuffer

指定容纳读入数据的一个缓冲区。除非读操作执行完毕,否则不要访问这个缓冲区。

3、nNumberOfBytesToRead

要读入的字节数。

4、lpOverlapped

一个指向OVERLAPPED类型的结构体指针,定义了一个异步操作的结构。使用这个函数时,结构中的hEvent字段会被忽略

5、lpCompletionRoutine

回调函数的返回值。 [1] 

返回值

返回TRUE表示成功;

返回FALSE表示失败,并可用GetLastError得到错误代码。 

### C++ 中实现 IOCP (输入/输出完成端口) #### 初始化 I/O 完成端口 创建一个I/O完成端口是使用`CreateIoCompletionPort`函数。此函数可以将文件句柄与特定的完成端口关联起来,即使传入的是`INVALID_HANDLE_VALUE`也可以成功创建一个未绑定任何文件句柄的完成端口对象[^1]。 ```cpp HANDLE m_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if (m_hIOCompletionPort == NULL) { // 处理错误情况 } ``` #### 创建线程池并将线程关联到I/O完成端口 对于每一个要监听I/O事件的工作线程,在启动时应该调用`GetQueuedCompletionStatus`等待来自该端口的通知消息。这通常意味着在一个循环里不断检查是否有新的已完成的操作需要处理: ```cpp DWORD WINAPI WorkerThread(LPVOID lpParam) { DWORD dwBytes; ULONG_PTR completionKey; LPOVERLAPPED overlapped; while (true) { BOOL ret = GetQueuedCompletionStatus( static_cast<HANDLE>(lpParam), &dwBytes, &completionKey, &overlapped, INFINITE); if (!ret && GetLastError() != ERROR_ABANDONED_WAIT_0) break; // 错误处理 // 进行业务逻辑处理... delete overlapped; } return 0; } // 启动多个工作线程 for(int i = 0 ;i < threadCount;i++) { CreateThread(NULL, 0, WorkerThread, m_hIOCompletionPort, 0, NULL); } ``` #### Overlapped 结构体初始化以及执行异步I/O操作 当准备发起一次异步读写请求之前,先分配并设置好相应的重叠结构实例,之后通过像`ReadFileEx`, `WriteFileEx`这样的API来进行实际的数据传输动作,并把刚才构建好的参数传递过去以便操作系统知道该如何回调通知结果给应用程序层面上下文环境中的指定位置。 ```cpp struct MyOverlapped : public OVERLAPPED { char buffer[BUFFER_SIZE]; }; MyOverlapped* pOverlap = new MyOverlapped(); memset(pOverlap, 0, sizeof(MyOverlapped)); BOOL success = ReadFileEx(hFile, pOverlap->buffer, BUFFER_SIZE, reinterpret_cast<LPOVERLAPPED>(pOverlap), [](DWORD errorCode, DWORD numberOfBytesTransfered, LPOVERLAPPED lpOverlapped){ // 自定义完成例程 }); if(!success) { /* ... */ } ``` #### 等待并处理I/O事件 一旦某个由上述方式触发过的异步过程结束,则会自动向对应的完成端口中投入一条记录;此时只要有一个处于闲置状态下的工作者线程就会立即被唤醒去获取这条信息进而继续后续的任务流程控制流走向直至整个程序终止运行或者遇到其他异常状况为止。 以上就是关于如何利用C++语言特性配合Windows API接口来搭建基于IOCP模型的服务端框架的大致思路概述[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值