代码如下:
// ProcessCommunicate.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#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;
}