重叠IO--命名管道同时进行读写操作
弄了一整天了,总算初步完成以下功能:
创建一个命名管道作为服务器,以重叠IO的方式;
创建一个客户端,可同时启动多个客户端;
服务器线程中对接入的客户端进行同时读和写操作;
每个客户端对服务器在线程中进行同时读和写操作;
测试开启一个服务器+20个客户端无任何压力。
服务器代码(一个读线程,一个写线程,不断的和客户端进行读写操作):
// PipeServer.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <process.h> #include <Windows.h> #include <iostream> using namespace std; #define BUFFERSIZE 256 #define STR_NAMEPIPE "\\\\.\\Pipe\\ServerPipe" #define MAX_CLIENTS 30 int WaitFinish(HANDLE hPipe,OVERLAPPED &tagOver); static unsigned int __stdcall ThreadReadFile(void *pData) { HANDLE hPipe = (HANDLE)pData; char szReadBuf[256]={0}; DWORD dwReadSize=0; OVERLAPPED tagOver; memset(&tagOver,0x0,sizeof(tagOver)); tagOver.hEvent = CreateEvent(NULL,//默认属性 TRUE,//手工reset TRUE,//初始状态signaled NULL);//未命名 while(1) { //读 int nRet = ReadFile(hPipe,&szReadBuf,sizeof(szReadBuf),&dwReadSize,&tagOver); if(nRet && dwReadSize ==0) { // this is the end of the file CloseHandle(hPipe); break; } if(WaitFinish(hPipe,tagOver) != 0) return -1; string strBuf = szReadBuf; printf("Client Msg: %s\n",strBuf.c_str()); memset(szReadBuf,0x0,sizeof(szReadBuf)); } return 0; } static unsigned int __stdcall ThreadWriteFile(void *pData) { HANDLE hPipe = (HANDLE)pData; char szWriteBuf[256]="服务器数据"; DWORD dwReadSize=0; OVERLAPPED tagOver; memset(&tagOver,0x0,sizeof(tagOver)); tagOver.hEvent = CreateEvent(NULL,//默认属性 TRUE,//手工reset TRUE,//初始状态signaled NULL);//未命名 while(1) { //写 DWORD dwHadWrite = 0; int nRet = WriteFile(hPipe,szWriteBuf,strlen(szWriteBuf),&dwHadWrite,&tagOver); if(WaitFinish(hPipe,tagOver) != 0) return -1; printf("Server WriteFile>>>>>>>>>:%s\n",szWriteBuf); Sleep(3000); } return 0; } int WaitFinish(HANDLE hPipe,OVERLAPPED &tagOver) { bool bPendingIO = false; switch(GetLastError()) { //正在连接中 case ERROR_IO_PENDING: bPendingIO = true; break; //已经连接 case ERROR_PIPE_CONNECTED: SetEvent(tagOver.hEvent); break; } DWORD dwWait = -1; DWORD dwTransBytes = -1; //等待读写操作完成 dwWait = WaitForSingleObject(tagOver.hEvent,INFINITE); switch(dwWait) { case 0: if (bPendingIO) { //获取Overlapped结果 if( GetOverlappedResult(hPipe,&tagOver,&dwTransBytes,FALSE) == FALSE) { printf("ConnectNamedPipe failed %d\n",GetLastError()); return -1; } } break; // 读写完成 case WAIT_IO_COMPLETION: break; } return 0; } int _tmain(int argc, _TCHAR* argv[]) { HANDLE hPipe=NULL; while(1) { hPipe = CreateNamedPipeA(STR_NAMEPIPE, PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,//FILE_FLAG_OVERLAPPED重叠IO //PIPE_TYPE_BYTE|PIPE_READMODE_BYTE, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,//不对数量进行限制 0,0,1000,NULL); if (hPipe == INVALID_HANDLE_VALUE) { printf("CreateNamedPipe failed!\n"); return -1; } printf("服务器通道启动\nCreateNamedPipe Success!\n"); int nRet = 0; OVERLAPPED tagOver; memset(&tagOver,0x0,sizeof(tagOver)); tagOver.hEvent = CreateEvent(NULL,//默认属性 TRUE,//手工reset TRUE,//初始状态signaled NULL);//未命名 nRet = ConnectNamedPipe(hPipe,&tagOver); if (nRet) { printf("ConnectNamedPipe failed! %d\n",GetLastError()); return -2; } if(WaitFinish(hPipe,tagOver) != 0) return -1; //读 HANDLE hHandle = (HANDLE)_beginthreadex(0,0,ThreadReadFile,hPipe,0,0); CloseHandle(hHandle); //写 HANDLE hWHandle = (HANDLE)_beginthreadex(0,0,ThreadWriteFile,hPipe,0,0); CloseHandle(hWHandle); } system("pause"); return 0; if (DisconnectNamedPipe(hPipe)==0) { printf("DisconnectNamedPipe error!\n"); return -4; } CloseHandle(hPipe); system("pause"); return 0; }
客户端实现(一个读线程,一个写线程,不断的和服务器进行读写操作):
// PipeClient.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> #include <process.h> #include <iostream> using namespace std; #define BUFFERSIZE 256 #define STR_NAMEPIPE "\\\\.\\Pipe\\ServerPipe" int WaitFinish(HANDLE hPipe,OVERLAPPED &tagOver) { bool bPendingIO = false; switch(GetLastError()) { //正在连接中 case ERROR_IO_PENDING: bPendingIO = true; break; //已经连接 case ERROR_PIPE_CONNECTED: SetEvent(tagOver.hEvent); break; } DWORD dwWait = -1; DWORD dwTransBytes = -1; //等待读写操作完成 dwWait = WaitForSingleObject(tagOver.hEvent,INFINITE); switch(dwWait) { case 0: if (bPendingIO) { //获取Overlapped结果 if( GetOverlappedResult(hPipe,&tagOver,&dwTransBytes,FALSE) == FALSE) { printf("ConnectNamedPipe failed %d\n",GetLastError()); return -1; } } break; // 读写完成 case WAIT_IO_COMPLETION: break; } return 0; } static unsigned int __stdcall ThreadReadFile(void *pData) { HANDLE hPipe = (HANDLE)pData; char szReadBuf[256]={0}; DWORD dwReadSize=0; OVERLAPPED tagOver; memset(&tagOver,0x0,sizeof(tagOver)); tagOver.hEvent = CreateEvent(NULL,//默认属性 TRUE,//手工reset TRUE,//初始状态signaled NULL);//未命名 while(1) { //读 int nRet = ReadFile(hPipe,szReadBuf,sizeof(szReadBuf),&dwReadSize,&tagOver); if(WaitFinish(hPipe,tagOver) != 0) return -1; printf("Server Msg: %s\n",szReadBuf); } return 0; } static unsigned int __stdcall ThreadWriteFile(void *pData) { HANDLE hPipe = (HANDLE)pData; char szWriteBuf[256]="客户端数据"; DWORD dwReadSize=0; OVERLAPPED tagOver; memset(&tagOver,0x0,sizeof(tagOver)); tagOver.hEvent = CreateEvent(NULL,//默认属性 TRUE,//手工reset TRUE,//初始状态signaled NULL);//未命名 int nPID = getpid(); sprintf_s(szWriteBuf,sizeof(szWriteBuf),"%s PID=%d",szWriteBuf,nPID); while(1) { DWORD dwHadWrite = 0; int nRet = WriteFile(hPipe,szWriteBuf,strlen(szWriteBuf),&dwHadWrite,&tagOver); if(WaitFinish(hPipe,tagOver) != 0) return -1; printf("Client WriteFile>>>>>>>>>:%s\n",szWriteBuf); Sleep(1000); } return 0; } int _tmain(int argc, _TCHAR* argv[]) { HANDLE hPipe=NULL; DWORD dwReadSize = 0; char szBuf[BUFFERSIZE]={0}; if (WaitNamedPipeA(STR_NAMEPIPE,NMPWAIT_WAIT_FOREVER)==0) { printf("WaitNamedPipeA error\n"); return -1; } hPipe = CreateFileA(STR_NAMEPIPE,GENERIC_READ|GENERIC_WRITE,0,NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); printf("客户端启动\n"); if(hPipe == INVALID_HANDLE_VALUE) { printf("CreateFileA error\n"); return -2; } //读 HANDLE hHandle = (HANDLE)_beginthreadex(0,0,ThreadReadFile,hPipe,0,0); CloseHandle(hHandle); //写 HANDLE hWHandle = (HANDLE)_beginthreadex(0,0,ThreadWriteFile,hPipe,0,0); CloseHandle(hWHandle); system("pause"); return 0; }
posted on 2017-10-12 21:27 zhuxian2009 阅读(734) 评论(0) 编辑 收藏 举报