이 영역을 누르면 첫 페이지로 이동
웬디의 기묘한 이야기 블로그의 첫 페이지로 이동

웬디의 기묘한 이야기

페이지 맨 위로 올라가기

웬디의 기묘한 이야기

C/C++ Windows Hooking 개발자의 블로그 입니다! 이곳은 개발 외에도 저의 취미들이 공유되는 기묘한 이야기가 펼쳐집니다.

[C/C++] IPC - Pipe server simple example

  • 2015.12.21 17:01
  • ⌨ DEVELOPMENT/C++
반응형


PIPE Server

프로세스 간 통신(Inter-Process Communication, IPC) 기법 중 하나인 PIPE 통신 입니다.


Pipe는 프로세스간에 바이트 스트림을 전송하기 위한 통로의 개념으로 로컬 통신으로 사용하기가 아주 편리한 기법 입니다. (소켓을 이용할수도 있겠지만 로컬 통신에선 포트까지 열어야하는 부담이 있기때문에 비교적 부담이 적은 Pipe를 사용합니다)

Pipe는 Named Pipe와 Anonymous Pipe로 나뉘어지며, IPC에선 주로 Named Pipe가 사용됩니다.
* Anonymous pipe는 사용성이 불편하고, 비동기 및 양방향 입출력이 지원되지 않는 구식 방식이기 때문입니다.


서버에서 하는 역할을 보겠습니다.


[초기화]
1. CreateNamedPipe 를 이용하여 Pipe 서버를 생성
2. ConnectNamedPipe 를 이용하여 Client 접속 대기


[사용]

- client data read
- client data write


…


[종료]
3. FlushFileBuffers로 통신중이던 버퍼를 비우고
4. DisconnectNamedPipe로 Pipe 서버를 닫고
5. CloseHandle로 Pipe Handle을 닫습니다.


이처럼 간단하게 파이프 서버를 작성할 수 있습니다.



namespace pipe {
class server {

public:
    server(
        __in LPCTSTR pipe_name,
        __in const size_t max_instances,
        __in_opt SECURITY_ATTRIBUTES* secutiry_attributes = nullptr
        ) : _pipe(INVALID_HANDLE_VALUE), _max_instances(max_instances) {

        do {
            if (pipe_name == nullptr || max_instances <= 0) {
                break;
            }

            _pipe = ::CreateNamedPipe(
                pipe_name,
                (PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED),
                (PIPE_TYPE_MESSAGE | PIPE_WAIT),
                static_cast<DWORD>(_max_instances), // max instances
                0, 0, 0,
                secutiry_attributes
                );

            if (_pipe == INVALID_HANDLE_VALUE) {
                break;
            }

        } while (false);
    }

    ~server() {
        disconnect();
    }

    bool accept() {
        bool result = false;

        do {
            
            //
            // Wait for the client to connect; if it succeeds, the function returns a nonzero value.
            // If the function returns zero, GetLastError returns ERROR_PIPE_CONNECTED. 
            //

            BOOL connected = ::ConnectNamedPipe(_pipe, nullptr);
            if (! (connected ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED)) ) {
                break;
            }

            result = true;

        } while (false);

        return result;
    }

    bool read(
        __out size_t& bytes_read,
        __out void* read_buffer,
        __in const size_t read_buffer_size
        ) {

        bool result = false;
        DWORD real_bytes_read = 0;

        do {
            if (!ReadFile(
                _pipe,
                read_buffer,
                static_cast<DWORD>(read_buffer_size),
                &real_bytes_read,
                nullptr)
                ) {
                break;
            }

            if (real_bytes_read == 0) {
                break;
            }

            bytes_read = real_bytes_read;
            result = true;
        } while (false);

        return result;
    }

    bool write(
        __out size_t& bytes_written,
        __in void* write_data,
        __in const size_t write_data_size
        ) {

        bool result = false;
        DWORD real_bytes_written = 0;

        do {
            if (!WriteFile(
                _pipe,
                write_data,
                static_cast<DWORD>(write_data_size),
                &real_bytes_written,
                nullptr)
                ) {
                break;
            }

            if (write_data_size != real_bytes_written) {
                break;
            }

            bytes_written = real_bytes_written;
            result = true;
        } while (false);

        return result;
    }

    bool verify() const {
        return _pipe != INVALID_HANDLE_VALUE;
    }

    void disconnect() {
        if (_pipe != INVALID_HANDLE_VALUE) {
            
            //
            // flush the pipe to allow the client to read the pipe's contents before disconnecting. 
            // then disconnect the pipe, and close the handle to this pipe instance. 
            //

            ::FlushFileBuffers(_pipe);
            ::DisconnectNamedPipe(_pipe);

            ::CloseHandle(_pipe);
        }
    }

    HANDLE& native_object() {
        return _pipe;
    }

private:
    HANDLE _pipe;
    size_t _max_instances;
    
};
} // namespace pipe

해당 클래스는 MSDN을 참조로 만들었습니다.
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa365588(v=vs.85).aspx

다음엔 클라이언트도 제작하여 서로 통신하는 방법을 보여드리겠습니다.

https://wendys.tistory.com/19







반응형
저작자표시 비영리 동일조건 (새창열림)

'⌨ DEVELOPMENT > C++' 카테고리의 다른 글

[C/C++] DLL injection. 다른 Process에 내 DLL Load 하기  (5) 2016.01.03
__cdecl, __stdcall, __fastcall x86 호출 규약(Calling Convention)  (4) 2016.01.01
[C/C++] FormatMessage 윈도우 GetLastError를 메시지로!!  (0) 2015.12.29
[C/C++] IPC - Pipe client simple example  (0) 2015.12.28
[C/C++] string replace all 문자열 모두 치환  (0) 2015.12.11
[C/C++] 폴더 전체 경로 중 파일명만 가져오기  (0) 2015.12.10
관리자 권한으로 생성한 MMF User 권한으로 접근하기  (0) 2015.04.03
System Error Codes (0-499)  (0) 2015.03.30

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [C/C++] FormatMessage 윈도우 GetLastError를 메시지로!!

    [C/C++] FormatMessage 윈도우 GetLastError를 메시지로!!

    2015.12.29
  • [C/C++] IPC - Pipe client simple example

    [C/C++] IPC - Pipe client simple example

    2015.12.28
  • [C/C++] string replace all 문자열 모두 치환

    [C/C++] string replace all 문자열 모두 치환

    2015.12.11
  • [C/C++] 폴더 전체 경로 중 파일명만 가져오기

    [C/C++] 폴더 전체 경로 중 파일명만 가져오기

    2015.12.10
다른 글 더 둘러보기

정보

웬디의 기묘한 이야기 블로그의 첫 페이지로 이동

웬디의 기묘한 이야기

  • 웬디의 기묘한 이야기의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록
  • 이야기

카테고리

  • 분류 전체보기 (204)
    • MY STORY (2)
    • 📸 WALKING WITH YOU (85)
      • 아이슬란드 신혼여행 이야기 (14)
      • 대한민국 구석구석 (62)
      • CONTAX N1 + T* 28-80mm (4)
      • SAMSUNG NX3000 (1)
      • 어느 멋진 날 (4)
    • ⌨ DEVELOPMENT (80)
      • BOOK:Review (1)
      • AI (13)
      • C++ (26)
      • Python (10)
      • WIndows Hooking (9)
      • Windows Kernel (3)
      • Design Pattern (3)
      • Debugging (9)
      • Tools (0)
      • Project (1)
      • Android (1)
      • 상업용 무료폰트 (4)
    • OS (4)
      • News (0)
      • Windows 일반 (4)
    • 모바일 (2)
      • 모바일 게임 (2)
    • 멘사 퍼즐 (9)
    • 생활 꿀 TIP (7)
      • 건강 (3)
      • 일상 (2)
    • 물생활 (8)
      • 골든볼 라미네지 롱핀 (8)
    • IT 기기 (2)
    • BLOG (4)
      • TISTORY BLOG TIP (3)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • c++
  • AI
  • c
  • 카페
  • 신혼여행
  • 아이슬란드
  • 해외여행
  • windbg

나의 외부 링크

  • kernel undocument api
  • 지구 관찰자의 일기
  • 지구와 지구곰

정보

WENDYS의 웬디의 기묘한 이야기

웬디의 기묘한 이야기

WENDYS

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © WENDYS. Designed by Fraccino.

티스토리툴바