代码如下:
// ProcessCommunicate.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> #define TEST_PIPE_NAME TEXT("\\\\.\\pipe\\MY_TEST_PIPE") //#define TEST_EVENT_NAME TEXT("Global\\EVENT_TEST_NAME") BOOL g_bExit = FALSE; struct OVERLAPPEDX { OVERLAPPED ov; TCHAR buf[1024]; HANDLE hPipe; }; void WINAPI CompleteReadRoutine(DWORD dwCode, DWORD dwBytesTrans, LPOVERLAPPED pOv); void WINAPI CompleteWriteRoutine(DWORD dwCode, DWORD dwBytesTrans, LPOVERLAPPED pOv); void FreeOverLappedX(OVERLAPPEDX** ppOv) { if (ppOv) { DisconnectNamedPipe((*ppOv)->hPipe); CloseHandle((*ppOv)->hPipe); GlobalFree(*ppOv); *ppOv = NULL; } } void RunAsClient() { BOOL bRet = WaitNamedPipe(TEST_PIPE_NAME, INFINITE); if (!bRet) { printf("WaitNamedPipe Fail, GetLastError:%d\n", GetLastError()); return; } HANDLE hFile = CreateFile(TEST_PIPE_NAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("Open Pipe Fail, GetLastError:%d\n", GetLastError()); return; } DWORD dwMode = PIPE_READMODE_MESSAGE; bRet = SetNamedPipeHandleState(hFile, &dwMode, NULL, NULL); if (!bRet) { printf("SetNamedPipeHandleState Fail, GetLastError:%d\n", GetLastError()); return; } DWORD dwWrite, dwRead; TCHAR buf[1024]={0}; Loop: printf("Please Input Message: "); memset(buf, 0, 1024*sizeof(TCHAR)); _tscanf(TEXT("%s"), buf); if (!WriteFile(hFile, buf, (_tcslen(buf)+1)*sizeof(TCHAR), &dwWrite, NULL)) { printf("WriteFile Fail, GetLastError:%d\n", GetLastError()); return; } if (_tcscmp(buf, TEXT("quit"))) { do { memset(buf, 0, 1024*sizeof(TCHAR)); bRet = ReadFile(hFile, buf, 1024*sizeof(TCHAR), &dwRead, NULL); } while (!bRet); _tprintf(TEXT("Client Recv: %s\n"), buf); goto Loop; } CloseHandle(hFile); } void WINAPI CompleteReadRoutine(DWORD dwCode, DWORD dwBytesTrans, LPOVERLAPPED pOv) { OVERLAPPEDX* pX = (OVERLAPPEDX*)pOv; _tprintf(TEXT("Server Recv: %s\n"), pX->buf); if (_tcscmp(pX->buf, TEXT("quit")) == 0) { g_bExit = TRUE; FreeOverLappedX(&pX); return; } HANDLE hPipe = pX->hPipe; if (hPipe == INVALID_HANDLE_VALUE) { printf("Open Pipe Fail!\n"); return; } printf("Please Reply: "); memset(pX->buf, 0, 1024*sizeof(TCHAR)); _tscanf(TEXT("%s"), pX->buf); if (!WriteFileEx(hPipe, pX->buf, (_tcslen(pX->buf)+1)*sizeof(TCHAR), pOv, CompleteWriteRoutine)) { printf("WriteFileEx Fail %d\n", GetLastError()); FreeOverLappedX(&pX); } } void WINAPI CompleteWriteRoutine(DWORD dwCode, DWORD dwBytesTrans, LPOVERLAPPED pOv) { OVERLAPPEDX* pX = (OVERLAPPEDX*)pOv; HANDLE hPipe = pX->hPipe; if (hPipe == INVALID_HANDLE_VALUE) { printf("Open Pipe Fail!\n"); return; } memset(pX->buf, 0, 1024*sizeof(TCHAR)); if (!ReadFileEx(hPipe, pX->buf, 1024*sizeof(TCHAR), pOv, CompleteReadRoutine)) { printf("ReadFileEx Fail %d\n", GetLastError()); FreeOverLappedX(&pX); } } void RunAsServer() { HANDLE hPipe; BOOL bIOIng, bOk, bFlag; DWORD dwErr, dwRet, dwWait; //OVERLAPPED OVERLAPPED ov; ov.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); OVERLAPPEDX* pX = NULL; //CREATENAMEDPIPE Loop: hPipe = CreateNamedPipe(TEST_PIPE_NAME, PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, 5000, NULL); if (hPipe == INVALID_HANDLE_VALUE) { printf("Server Pipe Create Fail!\n"); return; } //CONNECT bIOIng = FALSE; bOk = ConnectNamedPipe(hPipe, &ov); dwErr = GetLastError(); if (bOk) { printf("ConnectNamedPipe Fail GetLastError : %d!\n", dwErr); return; } switch (dwErr) { case ERROR_IO_PENDING: bIOIng = TRUE; break; case ERROR_PIPE_CONNECTED: if (SetEvent(ov.hEvent)) break; default: printf("ConnectNamedPipe Fail GetLastError: %d!\n", dwErr); break; } bFlag = TRUE; while (!g_bExit) { dwWait = WaitForSingleObjectEx(ov.hEvent, INFINITE, TRUE); switch (dwWait) { case WAIT_OBJECT_0: //Event Signal Or IO pending if (bIOIng) { //Pending if (!GetOverlappedResult(hPipe, &ov, &dwRet, FALSE)) { printf("GetOverlappedResult Fail %d!\n", GetLastError()); return; } } printf("Client Has Connect!\n"); //IO Over if (bFlag) { pX = (OVERLAPPEDX*)GlobalAlloc(GPTR, sizeof(OVERLAPPEDX)); if (!pX) { printf("GlobalAlloc Fail GetLastError: %d\n", GetLastError()); return; } memset(pX, 0, sizeof(OVERLAPPEDX)); pX->hPipe = hPipe; CompleteWriteRoutine(0, 0, (OVERLAPPED*)pX); goto Loop; } case WAIT_IO_COMPLETION: //printf("Server WAIT_IO_COMPLETION!\n"); break; default: printf("WaitForSingleObjectEx Fail GetLastError: %d\n", dwErr); return; } } printf("Server Exit!\n"); } int _tmain(int argc, _TCHAR* argv[]) { char mode; Loop: printf("Command As Following:\n 1 -- Client Mode \n 2 -- Server Mode \n q -- Quit \nPlease select : "); scanf("%c", &mode); if (mode == 10) { scanf("%c", &mode); } switch (mode) { case '1': printf("Run As Client!\n"); RunAsClient(); break; case '2': printf("Run As Server!\n"); RunAsServer(); break; case 'q': break; default: printf("Invalid mode!\n"); goto Loop; } system("@pause"); return 0; }