重叠式I/O的工作原理是: 向函数传递一个OVERLAPPED结构,然后使用GetOverlappedResult从原来的OVERLAPPED结构中取得结果.
通过看示例程序,自已觉得这个OVERLAPPED结构与事件对象相关,当某个特定的事件发生,那么这个结构的状态发生改变,然后可以通过这个状态来决定自己的下一步处理方案.下面是一个命名管道使用重叠式I/O的一个例子.其流程如下:
代码如下:
#include "stdafx.h"
#include <Windows.h>
#include <algorithm>
#define NUM_OF_PIPES 5
#define BUFF_SIZE 1024
using namespace std;
void ReleaseHandle(HANDLE hPipe)
{
cout<<"close handle "<<hPipe<<endl;
CloseHandle(hPipe);
}
int _tmain(int argc, _TCHAR* argv[])
{
//define var
HANDLE hPipes[NUM_OF_PIPES];
HANDLE hEvent[NUM_OF_PIPES];
char buff[NUM_OF_PIPES][BUFF_SIZE];
BOOL bDataRead[NUM_OF_PIPES];
OVERLAPPED overlapped[NUM_OF_PIPES];
//create named pipes
for (int i=0; i < NUM_OF_PIPES; ++i)
{
hPipes[i] = CreateNamedPipe(".//pipe//mypipes",PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, NUM_OF_PIPES, 0,0, 1000, NULL);
if ( INVALID_HANDLE_VALUE == hPipes[i] )
{
cout<<"The "<< i <<" pipe create failed"<<endl;
cout<<GetLastError()<<endl;
}
else
{
cout<<"The "<< i+1 <<" pipe create successed : "<<hPipes[i]<<endl;
}
}
//create event object for each named pipe
for (int i = 0 ;i < NUM_OF_PIPES; ++i)
{
hEvent[i] = CreateEvent(NULL,TRUE,FALSE,NULL);
if ( NULL == hEvent[i])
{
cout<<"create event object failed with error : "<< GetLastError() <<endl;
}
else
{
cout<<"create "<< i+1 <<"event objects successed : "<<hEvent<<endl;
}
bDataRead[i] = FALSE;
}
//listen each named pipe
for (int i = 0; i < NUM_OF_PIPES; ++i)
{
ZeroMemory(&overlapped[i],sizeof(OVERLAPPED));
overlapped[i].hEvent = hEvent[i];
if (ConnectNamedPipe(hPipes[i], &overlapped[i]) == 0)
{
cout<< hPipes[i]<<" start named pipe listen server failed with error :";
if (GetLastError() == ERROR_IO_PENDING)
{
cout<<"no error"<<endl;
}
else
{
cout<<GetLastError()<<endl;
}
}
else
{
cout<<hPipes[i]<<"begin to listen"<<endl;
}
}
cout<<endl<<"server is started now"<<endl;
//read and echo message from client
while (1)
{
DWORD ret = WaitForMultipleObjects(NUM_OF_PIPES,hEvent,FALSE, INFINITE);
if ( WAIT_FAILED == ret)
{
cout<<"listen error,and exit process"<<endl;
return 0;
}
//reset event object
DWORD pipe = ret - WAIT_OBJECT_0;
ResetEvent(hPipes[pipe]);
//deal with the connect, use GetOverlappedResult
}
//close pipes handle
//for_each( &hPipes[0], &hPipes[0]+NUM_OF_PIPES,ReleaseHandle);
return 0;
}