상세 컨텐츠

본문 제목

08.2 파이프 방식의 IPC

Programming/Windows System

by RACC8N 2020. 4. 18. 18:47

본문

파이프의 종류

- 이름없는 파이프 (Anonymous Pipe)

- 이름있는 파이프 (Named Pipe)

 

메일슬롯과 이름없는 파이프 비교

- 메일슬롯 :  서로 관련이 없는 프로세스들(네트워크로 연결되어 통신하는 프로세스들이나 부모 자식간의 연관 관계가 전혀 없는 프로세스들) 사이에서 통신할 때 유용

- 이름없는 파이프 : 지극히 관계가 있는(부모 자식관계) 프로세스들 사이에서 통신할 때 유용

 

메일슬롯과 이름있는 파이프 비교

- 메일슬롯 : 단방향 통신, 브로드캐스팅 방식 지원

- 이름있는 파이프 : 양방향 통신

 

● 메일슬롯 : 브로드캐스트 방식의 단방향 통신방식을 취하며, 메일슬롯에 할당된 주소를 기반으로 통신하기 때문에 관계없는 프로세스들 사이에서도 통신이 가능하다.

 

● 이름없는 파이프 : 단방향 통신방식을 취하며, 파이프를 통해서 생성된 핸들을 기반으로 통신하기 때문에 프로세스들 사이에는 관계가 있어야 한다.

 

● 이름있는 파이프 : 이름이 있다는 것은 주소 정보가 있다는 것. 메일슬롯과 유사하지만, 브로드캐스트 방식을 지원하지 않는 대신 양방향 통신이 가능하다.

 

이름없는 파이프 (Anonymous Pipe)

데이터를 한쪽 방향으로 전송할 수 있다. (파이프를 통해서 물이 위에서 아래로 흘러내리는 것처럼)

한쪽 끝에서는 데이터가 들어가고 다른 한쪽에서는 들어간 데이터가 흘러 나오는 것이 파이프의 원리이다.

즉 파이프는 두 개의 끝을 가지고 있다. 따라서 파이프 생성 시 각각의 끝에 접근하기 위한 두 개의 핸들을 얻는다.

 

이름없는 파이프 생성 함수 : CreatePipe()

hReadPipe 데이터를 읽기 위한 파이프 끝에 해당하는 핸들을 얻음
hWritePipe 데이터를 쓰기 위한 파이프 끝에 해당하는 핸들을 얻음
lpPipeAttributes 보안 속성 지정
nSize 파이프의 버퍼 사이즈를 지정 [ 0 : default ] (파이프의 길이를 지정한다고 생각)

자식 프로세스를 생성하면서, 입력용 혹은 출력용 핸들을 상속한다면, 부모 자식 프로세스간에 메시지 전송이 가능해진다.

 

이름있는 파이프(Named Pipe)

이름있는 파이프의 핵심은 양방향 통신이다.

 

Server는 CreateNamedPipe로 이름있는 파이프를 생성하고 ConnectNamedPipe로 연결 대기 상태로 만들어야 한다.

Client는 CreateFile를 통해 대기 상태인 파이프에 연결을 한다.

이름있는 파이프 생성 함수 : CreateNamedPipe()

lpName 파이프의 이름을 지정 (\\.\pipe\pipename)
dwOpenMode

PIPE_ACCESS_DUPLEX : 읽기,쓰기 가능

PIPE_ACCESS_INBOUND : 읽기만 가능(서버 입장에서)

PIPE_ACCSEE_OUTBOUND : 쓰기만 가능(서버 입장에서)

dwPipeMode 데이터 전송 타입, 데이터 수신 타입, 블로킹 모드 3가지를 설정
nNaxInstance

생성할 수 있는 파이프의 최대 개수를 지정 (지정하는 개수만큼 파이프 클라이언트의 연결 요청을 수용할 수 있음) 

PIPE_UNLIMITED_INSTACES : 생성 가능한 최대 개수

nOutBufferSize 이름있는 파이프의 출력 버퍼 사이즈를 지정 ( 0 : default )
nInBufferSize 이름있는 파이프의 입력 버퍼 사이즈를 지정 ( 0 : default )
nDefaultTimeOut WaitNamedPipe 함수에 적용할 기본 만료 시간을 지정
lpSecurityAttributes 보안 속성 지정

dwPipeMode 설정 값

데이터 전송방식 PIPE_TYPE_BYTE (바이트), PIPE_TYPE_MESSAGE (메시지)
데이터 수신방식 PIPE_READMODE_BYTE(바이트), PIPE_READMODE_MESSAGE (메시지)
함수 리턴방식 PIPE_WAIT (블로킹), PIPE_NOWAIT (넌-블로킹) (무조건 PIPE_WAIT 사용)

문자열을 주고 받는다 : PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT

바이너리 데이터를 주고받는다 : PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT

 

생성한 파이프의 연결 요청 대기 상태 변경 함수 : ConnectNamedPipe()

hNamedPipe CreateNamedPipe 함수 호출을 통해서 생성한 파이프의 핸들
lpOverlapped 중첩 I/O를 위한 전달인자 (우선 NULL 설정)

 

파이프의 상태 확인 함수 : WaitNamedPipe() (파이프의 상태를 확인 (연결 가능한 상태가 될 때까지 블로킹 상태 유지)

lpNamedPipeName 상태 확인의 대상이 되는 파이프 이름 지정
nTimeOut

타임-아웃 시간을 설정

NMPWAIT_WAIT_FOREVER : 연결 가능한 상태가 될 때까지 기다림

NMPWAIT_USE_DEFAULT_WAIT : 디폴트 시간만큼 기다림 

(디폴트 시간 : CreateNamedPipe 함수의 7번째 인자)

 

파이프의 속성 변경 함수 : SetNamedPipeHandleState()

hNamedPipe 파이프와의 연결 속성을 변경시키기 위한 핸들 지정
lpMode 읽기 모드와 함수 리턴방식에 대한 값을 OR연산으로 전달 (값을 담고있는 변수의 주소로 전달)
lpMaxCollectionCount

서버로 데이터를 보내기에 앞서서 버퍼링할 수 있는 최대 바이트 크기

(클라이언트와 서버가 같은 PC일 경우 반드시 NULL)

lpCollectionDataTimeOut

서버로 데이터를 보내기에 앞서서 버퍼링을 허용하는 최대 시간

(클라이언트와 서버가 같은 PC일 경우 반드시 NULL)

 

관련글 더보기

댓글 영역