// NamedPipeServer.h
#pragma once
namespace EventType
{
enum EventType
{
Exit,
Connect,
Max
};
}
class NamedPipeServer
{
public:
NamedPipeServer(LPCWSTR name);
~NamedPipeServer();
BOOL Start();
VOID Stop();
private:
std::wstring m_strName;
std::wstring m_strBuffer;
BOOL m_isStopped;
HANDLE m_hEvent[EventType::Max];
};
// NamedPipeServer.cpp
#include "stdafx.h"
#include "NamedPipeServer.h"
NamedPipeServer::NamedPipeServer(LPCWSTR name) :
m_strName(name),
m_strBuffer(),
m_isStopped(FALSE)
{
}
NamedPipeServer::~NamedPipeServer()
{
for (int i = 0; i < EventType::Max; ++i)
CloseHandle(m_hEvent[i]);
}
BOOL NamedPipeServer::Start()
{
OVERLAPPED oOverlapped;
HANDLE hPipe = NULL;
WCHAR buffer[MAX_BUFFER_SIZE] = { 0, };
DWORD dwRead;
while (m_isStopped == FALSE)
{
hPipe = CreateNamedPipe(m_strName.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, MAX_BUFFER_SIZE * sizeof(WCHAR), MAX_BUFFER_SIZE * sizeof(WCHAR), 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE)
return FALSE;
for (int i = 0; i < EventType::Max; ++i)
{
m_hEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hEvent[i] == NULL)
return FALSE;
}
ZeroMemory(&oOverlapped, sizeof(OVERLAPPED));
oOverlapped.hEvent = m_hEvent[EventType::Connect];
if (ConnectNamedPipe(hPipe, &oOverlapped) == 0)
{
if (GetLastError() != ERROR_IO_PENDING)
{
CloseHandle(hPipe);
return FALSE;
}
}
DWORD dwEvent = WaitForMultipleObjects(EventType::Max, m_hEvent, FALSE, INFINITE);
switch (dwEvent)
{
case EventType::Exit:
break;
case EventType::Connect:
ReadFile(hPipe, buffer, MAX_BUFFER_SIZE * sizeof(WCHAR), &dwRead, NULL);
if (0 < dwRead)
m_strBuffer = buffer;
break;
}
for (int i = 0; i < EventType::Max; ++i)
CloseHandle(m_hEvent[i]);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
}
return TRUE;
}
VOID NamedPipeServer::Stop()
{
m_isStopped = TRUE;
SetEvent(m_hEvent[EventType::Exit]);
}
// NamedPipeClient.h
#pragma once
class NamedPipeClient
{
public:
NamedPipeClient();
~NamedPipeClient();
BOOL Open(LPCWSTR name);
BOOL Send(LPCWSTR message);
private:
HANDLE m_hPipe;
};
// NamedPipeClient.cpp
#include "stdafx.h"
#include "NamedPipeClient.h"
NamedPipeClient::NamedPipeClient() : m_hPipe(NULL)
{
}
NamedPipeClient::~NamedPipeClient()
{
CloseHandle(m_hPipe);
}
BOOL NamedPipeClient::Open(LPCWSTR name)
{
SetLastError(ERROR_SUCCESS);
// Try to open a named pipe; wait for it, if necessary.
for (int retry = 0; retry < 3; ++retry)
{
m_hPipe = CreateFile(name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
// Break if the pipe handle is valid.
if (m_hPipe != INVALID_HANDLE_VALUE)
break;
// Exit if an error other than ERROR_PIPE_BUSY occurs.
if (GetLastError() != ERROR_PIPE_BUSY)
return FALSE;
// All pipe instances are busy, so wait for 180 seconds.
if (WaitNamedPipe(name, 180000) == FALSE)
return FALSE;
}
return TRUE;
}
BOOL NamedPipeClient::Send(LPCWSTR message)
{
DWORD dwNumberOfBytesToWrite = (wcslen(message) + 1) * sizeof(WCHAR);
DWORD dwNumberOfBytesWritten;
return WriteFile(m_hPipe, message, dwNumberOfBytesToWrite, &dwNumberOfBytesWritten, NULL);
}
// main.cpp - Server
int main()
{
NamedPipeServer* pServer = new NamedPipeServer(L"\\\\.\\pipe\\PMAPipe");
std::thread pipe([=]
{
pServer->Start();
});
// for stop test
Sleep(300000);
pServer->Stop();
pipe.join();
if (pServer != NULL)
{
delete pServer;
pServer = NULL;
}
return EXIT_SUCCESS;
}
// main.cpp - Client
int main()
{
NamedPipeClient* pClient = new NamedPipeClient();
pClient->Open(L"\\\\.\\pipe\\PMAPipe");
pClient->Send(L"FUCK THAT SHIT");
if (pClient != NULL)
{
delete pClient;
pClient = NULL;
}
return 0;
}
'Programming > C / C++' 카테고리의 다른 글
int64_t 값 출력하기 (0) | 2015.08.15 |
---|---|
to read UTF-8 XML using TinyXML (0) | 2015.08.06 |
Windows Named Pipe 구현 간단 정리 (0) | 2015.06.11 |
GetSystemMetrics (0) | 2015.06.04 |
Singleton (0) | 2015.06.02 |