그외/뇌를 자극하는 윈도우즈 시스템 프로그래밍

Chapter8) 프로세스 간 통신(IPC) 2 - 이름 있는 파이프 예제

아는개발자 2023. 4. 28. 12:43
/*
* namedpipe_server.cpp
* 
* 프로그램 설명: 이름 있는 파이프 서버
*/

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#define BUF_SIZE 1024
int CommToClient(HANDLE);

int _tmain(int argc, TCHAR* argv[])
{
	LPCTSTR pipeName = _T("\\\.\\pipe\\ simple_pipe");
	HANDLE hPipe;
	while (1) {
		hPipe = CreateNamedPipe(
			pipeName, PIPE_ACCESS_DUPLEX,
			PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
			PIPE_UNLIMITED_INSTANCES,
			BUF_SIZE,
			BUF_SIZE,
			20000, NULL);
		if (hPipe == INVALID_HANDLE_VALUE) {
			_tprintf(_T("CreatePipe failed"));
			return -1;
		}

		BOOL isSuccess = 0;
		isSuccess = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
		if (isSuccess) {
			CommToClient(hPipe);
		}
		else {
			CloseHandle(hPipe);
		}
	}

	return 1;
}

int CommToClient(HANDLE hPipe)
{
	TCHAR fileName[MAX_PATH];
	TCHAR dataBuf[BUF_SIZE];

	DWORD fileNameSize;
	
	BOOL isSuccess;
	isSuccess = ReadFile(hPipe, fileName, MAX_PATH * sizeof(TCHAR), &fileNameSize, NULL);
	if (!isSuccess || fileNameSize == 0) {
		_tprintf(_T("Pipe read message error!\n"));
		return -1;
	}

	FILE* filePtr = _tfopen(fileName, _T("r"));
	if (filePtr == NULL) {
		_tprintf(_T("File open fault!\n"));
		return -1;
	}

	DWORD bytesWritten = 0;
	DWORD bytesRead = 0;

	while (!feof(filePtr)) {
		bytesRead = fread(dataBuf, 1, BUF_SIZE, filePtr);
		WriteFile(hPipe, dataBuf, bytesRead, &bytesWritten, NULL);
		if (bytesRead != bytesWritten) {
			_tprintf(_T("Pipe write message error\n"));
			break;
		}
	}

	FlushFileBuffers(hPipe);
	DisconnectNamedPipe(hPipe);
	CloseHandle(hPipe);

	return 1;
}
/*
* namedpipe_client.cpp
* 
* 프로그램 설명: 이름 있는 파이프 클라이언트
*/

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#define BUF_SIZE 1024

int _tmain(int argc, TCHAR* argv[])
{
	HANDLE hPipe;
	TCHAR readDataBuf[BUF_SIZE + 1];
	LPCTSTR pipeName = _T("\\\.\\pipe\\ simple_pipe");

	while (1) {
		hPipe = CreateFile(pipeName,
			GENERIC_READ | GENERIC_WRITE,
			0, NULL, OPEN_EXISTING, 0, NULL);

		if (hPipe != INVALID_HANDLE_VALUE) {
			_tprintf(_T("Could not open pipe\n"));
			return 0;
		}

		if (!WaitNamedPipe(pipeName, 20000)) {
			_tprintf(_T("Could not open pipe\n"));
			return 0;
		}
	}

	DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
	BOOL isSuccess = SetNamedPipeHandleState(hPipe, &pipeMode, NULL, NULL);
	if (!isSuccess) {
		_tprintf(_T("SetNamedPipeHandleState failed\n"));
		return 0;
	}

	LPCTSTR fileName = _T("news.txt");
	DWORD bytesWritten = 0;
	isSuccess = WriteFile(hPipe, fileName, (_tcslen(fileName) + 1), &bytesWritten, NULL);
	if (!isSuccess) {
		_tprintf(_T("WrtieFile failed\n"));
		return 0;
	}

	DWORD bytesRead = 0;
	while (1) {
		isSuccess = ReadFile(hPipe, readDataBuf, BUF_SIZE * sizeof(TCHAR), &bytesRead, NULL);
		if (!isSuccess && GetLastError() != ERROR_MORE_DATA)
			break;

		readDataBuf[bytesRead] = 0;
		_tprintf(_T("%s \n"), readDataBuf);
	}
	
	CloseHandle(hPipe);

	return 0;
}
ERROR CODE가 ERROR_PATH_NOT_FOUND로 뜨면서 실행되지 않는다.
이런 경우에는 어떻게 해결해야하는지 알아봐야겠다.