Win32에서 IPC(Inter Process Communication)의 하나의 방법인 Pipe에 관한 간단한 Server/Client 예제이다.
파이프를 하나만 만들고 단방향 서버 클라이언트이다.
서버는 보내기만 하고, 클라이언트는 받기만 한다.
// PipeServer2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
// "\\\\.\\pipe\\RenToImaging"라는 이름의 파이프를 생성한다.
// 파이프는 항상 \\.\pipe\(이름)에 생성 되어야 한다.
HANDLE hPipe = ::CreateNamedPipe(L"\\\\.\\pipe\\RenToImaging",
PIPE_ACCESS_DUPLEX, // 양방향
PIPE_TYPE_BYTE, // 텍스트 모드
255, // 최대 255개 인스턴스
4096, // 출력 버퍼
0, // 입력 버퍼
1, // 타임아웃
NULL);// 보안속성
while(true)
{
// 이전에 연결된 파이프가 있는지 초기화 한다.
::DisconnectNamedPipe(hPipe);
// 클라이언트가 연결되기를 기다린다.
// 클라이언트가 연결되기 전에는 리턴되지 않는다.
BOOL bCon = ::ConnectNamedPipe(hPipe, NULL);
// bCon이 FALSE이고 GetLastError가 ERROR_PIPE_CONNECTED이면 정상 연결된 경우이므로 bCon을 TRUE로 해준다.
if(bCon == FALSE && ::GetLastError() == ERROR_PIPE_CONNECTED)
bCon = TRUE;
// 정상 연결일 경우
if(bCon == TRUE)
{
// WriteFile로 "Server"라는 문자열을 보내준다.
DWORD written;
BOOL bSuc = ::WriteFile(hPipe, L"Server", sizeof(wchar_t)*6, &written, NULL);
::wprintf(L"Connect\n");
::OutputDebugString(L"Connect\n");
// 버퍼에 있는것을 비우고 파이프를 Disconnect한다.
::FlushFileBuffers(hPipe);
::DisconnectNamedPipe(hPipe);
}
else
{
// 연결이 실패한 경우이다.
::wprintf(L"Connect fail..\n");
break;
}
}
// 파이프를 닫아준다.
::CloseHandle(hPipe);
return 0;
}
// PipeClient2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
while(true)
{
HANDLE hPipe = NULL;
for(;;)
{
// 파이프가 연결될 수 있는 상태까지 대기한다.
if(::WaitNamedPipe(L"\\\\.\\pipe\\RenToImaging", NMPWAIT_WAIT_FOREVER) == TRUE)
{
::OutputDebugString(L"Wait\n");
::wprintf(L"Wait\n");
// 파이프를 생성한다.
// 일반 파일과 동일하게 읽는다.
hPipe = ::CreateFile(L"\\\\.\\pipe\\RenToImaging", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(hPipe != INVALID_HANDLE_VALUE)
break;
}
}
::OutputDebugString(L"CreateFile\n");
::wprintf(L"CreateFile\n");
wchar_t wszBuffer[512] = {0,};
DWORD dwWritten;
// 파이프로부터 데이터를 전송 받는다.
BOOL bRet = ::ReadFile(hPipe, wszBuffer, 512, &dwWritten, NULL);
BYTE* pBuffer = (BYTE*)wszBuffer;
pBuffer += sizeof(size_t)*2;
::wprintf(L"%s\n", (wchar_t*)pBuffer);
// 파이프를 닫는다.
::FlushFileBuffers(hPipe);
::CloseHandle(hPipe);
// 잠시쉬고 다시 처음으로 돌아가 서버의 전송을 기다린다.
::Sleep(200);
}
return 0;
}
No comments:
Post a Comment