所谓完成端口,就是当事件触发时,io端口操作已完成。
此时完成的是上次执行过的操作,一般是readfile/writefile/waitforconnect。
所以一般的流程是:
添加等待事件->连接成功,readfile(相当于注册回调)。
写动作单独处理。
windows完成端口跟linux的epoll不同。
epoll的特点是,事件触发时,只是通知你io端口操作就绪,要自己执行io操作
// cpio_server.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <Windows.h>
#include <iostream>
#include <algorithm>
#include <tchar.h>
#include <process.h>
#define OP_ACCEPT 1
#define OP_READ 2
#define OP_WRITE 3
#define THREAD_NO 4
#define SIZE 1024
#define PIPE_NAME "\\\\.\\pipe\\completeio_pipe"
using namespace std;
struct PipeNode
{
PipeNode():hPipe(NULL), nOperationType(OP_ACCEPT),nLen(0)
{
memset(buf, 0, SIZE);
memset(&hOver, 0, sizeof(hOver));
}
PipeNode(HANDLE p):hPipe(p), nOperationType(OP_ACCEPT),nLen(0)
{
memset(buf, 0, SIZE);
memset(&hOver, 0, sizeof(hOver));
}
PipeNode(HANDLE p, OVERLAPPED op):hPipe(p), hOver(op), nOperationType(OP_ACCEPT),nLen(0)
{
memset(buf, 0, SIZE);
}
HANDLE hPipe;
OVERLAPPED hOver;
volatile DWORD nOperationType;
DWORD nLen;
char buf[SIZE];
};
std::vector<PipeNode*> g_pNodeList;
UINT WINAPI pipeThreadFun(LPVOID lpParam)
{
HANDLE hCompletion = (HANDLE)lpParam;
DWORD dwTrans = 0, dwErr = 0;
PipeNode* pipeNode = NULL;
OVERLAPPED *pOverlapped = NULL;
while(TRUE)
{
BOOL bOK = ::GetQueuedCompletionStatus(hCompletion, &dwTrans, (PULONG_PTR)&pipeNode, &pOverlapped, INFINITE);
dwErr = GetLastError();
if(pOverlapped == NULL)
{
printf("*******pOverlapped nulll: %d\r\n", GetLastError());
continue;
}
// 外部主动发起退出信号
if((int)pipeNode == -1)
{
printf("工作线程退出信号: %d\r\n", GetLastError());
break;
}
if(!bOK)
{
if (dwErr == ERROR_INVALID