Windows_/Windows32_API

Windows :: Named Pipe를 이용한 프로세스간 통신

sosal 2014. 7. 24. 10:07
반응형

/*

 * http://sosal.kr/

 * made by so_Sal

 */




앞서 Windows 09. Pipe를 이용한 프로세스간 통신 / 포스트에서
파이프에 대한 내용을 알아보았습니다.

일반 Pipe는 양방향 통신을 사용하며, 핸들을 기반으로 통신합니다.
따라서 핸들을 주고받을 수 있는 프로세스들 (흔히 부모-자식)처럼
특별한 관계가 있는 프로세스들끼리만이 통신할 수 있는 기법이었습니다.

하지만 Named Pipe는 파이프의 이름만 알고있다면
어떠한 관계에 있는 프로세스라도 통신이 가능하게 됩니다.


그럼 Named Pipe의 생성과정에 사용되는 함수들은?

// 서버가 하는일 //
CreateNamedPipe() -> ConnectNamedPipe().
CreateNamedPipe를 이용해서 파이프를 생성한 뒤
ConnectNamedPipe를 이용해서 다른 프로세스들이 파이프 연결요청을
기다리도록 파이프 상태를 변경합니다.
이제부터 클라이언트가 요청하기를 기다리면 됩니다..

// 클라이언트 //
CreateFile()
클라이언트는 단순히 서버가 만들어놓은 파이프를 연결하기 위해서
"연결요청"만 해주면 됩니다.
CreateFile 함수를 이용합니다.
이 함수는 파일을 생성하는 함수이지만, 메일슬롯, 파이프 등
IPC 연결요청을 하는 경우에 상당히 중요한 함수입니다.

차례대로 함수를 분석합니다.

 CreateNamedPipe(
    LPCWSTR lpName,
    DWORD dwOpenMode,
    DWORD dwPipeMode,
    DWORD nMaxInstances,
    DWORD nOutBufferSize,
    DWORD nInbufferSize,
    DWORD nDefaultTimeOut,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
  
  LPCWSTR lpName,   //파이프 이름을 지정합니다. :: \\\\.\\pipe\\pipename

  DWORD dwOpenMode, //3가지 종류의 open mode(flag)가 존재합니다.
  // PIPE_ACCESS_DUPLEX //읽기 + 쓰기 모드
  // PIPE_ACCESS_INBOUND //읽기 (서버입장에서의 읽기)
  // PIPE_ACCESS_OUTBOUND //쓰기 (서버입장에서의 쓰기)
  
  DWORD dwPipeMode, // 3가지 종류의 Pipe mode(flag)가 존재합니다.
  // PIPE_TYPE_BYTE, PIPE_TYPE_MESSAGE
  // └ 데이터 전송 형태 결정 :: 바이너리모드, 메시지 모드.
  // PIPE_READMODE_BYTE , PIPE_READMODE_MESSAGE
  // └ 데이터 수신 형태 결정 :: 바이너리모드, 메시지 모드.
  // PIPE_WAIT, PIPE_NOWAIT
  // └ PIPE_WAIT만 쓰입니다.
  // NOWAIT은 Microsoft Lan Manager version2.0과의 호환성을 위해 제공되는 인자

  DWORD nMaxInstances,
  // 생성할 수 있는 최대한의 파이프 갯수. 1~255 까지 허용.

  DWORD nOutBufferSize,
  // 파이프 출력 버퍼 사이즈. 0 입력 시 Windows default값

  DWORD nInbufferSize,
  // 파이프 입력 버퍼 사이즈. 0 입력 시 Windows default값

  DWORD nDefaultTimeOut,
  //WaitNamedPipe() 함수에 적용할 시간. 단위 : ms (1/1000초)

  LPSECURITY_ATTRIBUTES lpSecurityAttributes
  //보안 속성을 가지는 구조체

바로 위 DWORD nDefaultTimeOut, 변수 설명중에 WaitNamedPipe() 함수를 언급했는데
BOOL WaitNamedPipe(
    LPCTSTR lpNamedPipeName,  // 파이프 이름 지정
    DWORD nTimeOut //타임아웃 시간 설정.
);


BOOL ConnectNamedPipe(
     HANDLE hNamedPipe,
     LPOVERLAPPED lpOverlapped
  );

hNamedPipe :: CreateNamedPipe를 통해 호출된 파이프 핸들 전달
lpOverlapped :: 중첩 I/O를 위한 전달 인자.

HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAcess
      DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurity Attribute
      DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
      HANDLE hTemplateFile
);