반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

폴크(FOLC)

데이터 공유 방법 ( 다른 PC ) 본문

카테고리 없음

데이터 공유 방법 ( 다른 PC )

folcjin 2025. 5. 11. 20:45
728x90
반응형

Named Pipe 방식 (CreateNamedPipe)

1. 개요

  • Windows에서 제공하는 고속 메모리 기반 IPC (Inter-Process Communication) 방식
  • 프로세스 간 실시간으로 스트림 혹은 메시지를 전송할 수 있음
  • 파일처럼 보이지만 진짜 파일은 아님

구성 요소

  • 서버 프로세스:
    • CreateNamedPipe 로 파이프 생성
    • ConnectNamedPipe 로 클라이언트 연결 수신
  • 클라이언트 프로세스:
    • CreateFile 로 파이프에 연결
    • WriteFile, ReadFile 로 데이터 송수신

동작 흐름

  1. 서버가 \\.\pipe\MyPipe 라는 파이프를 생성
  2. 클라이언트가 해당 파이프에 연결 시도
  3. 연결 후 실시간 데이터 전송 가능 (버퍼 기반)

장점

  • 실시간성 우수 (메모리 기반 통신)
  • 디스크 접근이 없어 빠름
  • 읽기/쓰기 작업이 블로킹 또는 논블로킹으로 동작 가능
  • 양방향 통신 가능 (Full Duplex)

단점

  • 구현이 복잡 (에러 처리, 상태 관리 등 필요)
  • 클라이언트 연결 시도 시 시간 제한/대기 처리 필요
  • 보안 설정이 까다로울 수 있음 (다른 PC 간 통신 시)

 

< 예제 코드 >

 

서버 코드 -------

#include <windows.h>
#include <iostream>

#define PIPE_NAME L"\\\\.\\pipe\\MyNamedPipe"
-> \\\\.\\pipe\\  : Windows의 Named Pipe 네임스페이스 (특수 시스템 경로)
-> MyNamedPipe : 사용자가 지정한 파이프 이름 (고유 ID 역할)
-> 만약 원격 PC 와 연동해서 사용하는 경우에는
( 서버 쪽에서 CreateNamedPipe(L"\\\\.\\pipe\\MyNamedPipe") 로 생성한 파이프에, 클라이언트가 CreateFile(L" \\\\192.168.0.101\\pipe\\MyNamedPipe") 로 접속하는 구조입니다.

 


int main()
{
    HANDLE hPipe = CreateNamedPipeW(
        PIPE_NAME,                   // 파이프 이름
        PIPE_ACCESS_DUPLEX,         // 읽기/쓰기 양방향
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
        1,                          // 인스턴스 수 (동시 연결 허용 수)
        1024, 1024,                 // 출력/입력 버퍼 크기
        0,                          // 시간 제한 (기본값)
        NULL);                      // 보안 속성

    if (hPipe == INVALID_HANDLE_VALUE) {
        std::cerr << "CreateNamedPipe 실패! 오류: " << GetLastError() << std::endl;
        return 1;
    }

    std::wcout << L"클라이언트 연결 대기 중..." << std::endl;

    BOOL connected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

    if (connected) {
        std::wcout << L"클라이언트 연결됨!" << std::endl;

        char buffer[1024] = {0};
        DWORD bytesRead;

        if (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL)) {
            std::cout << "[수신]: " << buffer << std::endl;

            // 응답 메시지 전송
            const char* reply = "서버에서 응답 보냄!";
            DWORD bytesWritten;
            WriteFile(hPipe, reply, strlen(reply), &bytesWritten, NULL);
            std::cout << "[응답 전송 완료]" << std::endl;
        } else {
            std::cerr << "ReadFile 실패!" << std::endl;
        }
    } else {
        std::cerr << "ConnectNamedPipe 실패!" << std::endl;
    }

    CloseHandle(hPipe);
    return 0;
}

 

클라이언트 코드 -----

#include <windows.h>
#include <iostream>

#define PIPE_NAME L"\\\\192.168.0.101\\pipe\\MyNamedPipe "
-> \\\\.\\pipe\\  : Windows의 Named Pipe 네임스페이스 (특수 시스템 경로)
-> MyNamedPipe : 사용자가 지정한 파이프 이름 (고유 ID 역할)
-> 만약 원격 PC 와 연동해서 사용하는 경우에는
( 서버 쪽에서 CreateNamedPipe(L"\\\\.\\pipe\\MyNamedPipe") 로 생성한 파이프에, 클라이언트가 CreateFile(L" \\\\192.168.0.101\\pipe\\MyNamedPipe") 로 접속하는 구조입니다.

int main()
{
    HANDLE hPipe = INVALID_HANDLE_VALUE;

    // 무한 재시도 루프
    while (true) {
        hPipe = CreateFileW(
            PIPE_NAME,                   // 서버의 파이프 이름
            GENERIC_READ | GENERIC_WRITE,
            0, NULL,
            OPEN_EXISTING,
            0, NULL
        );

        if (hPipe != INVALID_HANDLE_VALUE) {
            std::cout << "파이프 연결 성공!" << std::endl;
            break;
        }

        DWORD error = GetLastError();
        if (error == ERROR_FILE_NOT_FOUND || error == ERROR_PIPE_BUSY) {
            std::cout << "서버 대기 중... 1초 후 재시도" << std::endl;
            Sleep(1000); // 1초 대기 후 재시도
            continue;
        } else {
            std::cerr << "파이프 연결 실패! 오류: " << error << std::endl;
            return 1;
        }
    }

    // 클라이언트 메시지 전송
    const char* message = "클라이언트가 보낸 메시지입니다.";
    DWORD bytesWritten;
    WriteFile(hPipe, message, strlen(message), &bytesWritten, NULL);
    std::cout << "보냄: " << message << std::endl;

    // 서버로부터 응답 수신
    char buffer[1024] = {0};
    DWORD bytesRead;
    ReadFile(hPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL);
    std::cout << "응답 수신: " << buffer << std::endl;

    // 연결 종료
    CloseHandle(hPipe);
    return 0;
}

728x90
반응형
사업자 정보 표시
사업자 등록번호 : -- | TEL : --