본문 바로가기
Program

[Program] (윈도우 시스템 프로그래밍) MailSlot 기반 IPC

by snwo 2021. 5. 23.

프로세스를 여러개 생성하는 경우, 프로세스간의 통신이 필요할 때가 있다.

프로세스간 데이터 송/수신은 메모리공유로 볼 수 있다.

공유할 수 있는 메모리공간에 A가 넣고, B 가 가져가면, 이것을 통신으로 볼 수 있다.

프로세스간 통신의 내부적인 메커니즘은 결국 메모리공유이다.

 

프로세스별 메모리 영역(가상메모리)은 완전히 분리되어있다.

안정선을 위해 os 가 막았는데, 같이 해결방안도 제시하고있다.

 

그것은, IPC (Inter Process Communication) 로, 이것을 이용해 프로세스간 통신을 할 수 있다.

 

그 중에서 MailSlot 기반 IPC 를 예제로 들어 설명해보려한다.

대충 이런 흐름

receiver 프로세스가 CreateMailslot 함수를 통해 우체통(MailSlot)을 만든다. 

그러면, sender 프로세스가 CreateFile 함수로 연결을 하고, WriteFile 함수로 데이터를 전송하는

단방향 파일기반 통신이다.

 

이 때, 여러개의 프로세스는 우체통의 이름을 같게할 수 있다. (ex: \\\\컴퓨터이름\\mailslot\mailbox )

 

또한, MailSlot 은 Broadcasting 을 지원해서, 여러 receiver 에게 한 번에 동일 메시지를 전송할 수 있고,

컴퓨터 이름에 *(별) 문자를 넣으면, 같은 네트워크상의 모든 컴퓨터의 해당 주소 (우체통 이름)

으로 메시지를 보낼 수 있다.

 

하지만, 서로 다른 컴퓨터에게 메시지를 전송할 때는 보통 TCP/IP 통신을 사용하므로

이러한 방식으로 쓰지는 않는다.

 

이제 간단한 예제로 확인해보자.

 

예제.gif

mailslot을 통해 단방향통신하고, EXIT 를 입력받으면 handle 을 닫고, 통신이 종료되게했습니다.

 

sender.c

더보기
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
32
33
34
35
36
37
#include<windows.h>
#include<stdio.h>
#include<string.h>
LPCSTR address=TEXT("\\\\.\\mailslot\\myslot");
 
int main(void){
    HANDLE hFile;
    char buffer[512];
    DWORD byteswritten;
    if((hFile=CreateFile(
        address,
        GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    ))==INVALID_HANDLE_VALUE){
        printf("createfile error %d",GetLastError());
    }
    
    while(1){
        printf("send_message > ");
        scanf("%s",buffer);
        WriteFile(
            hFile,
            buffer,
            strlen(buffer),
            &byteswritten,
            NULL
        );
        printf("%d bytes send\n",byteswritten);
        if(!strcmp(buffer,"EXIT")){
            CloseHandle(hFile);break;
        }
    }
}
cs

 

receiver.c

더보기

 

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
32
33
34
35
36
#include<windows.h>
#include<stdio.h>
 
LPCSTR address=TEXT("\\\\.\\mailslot\\myslot");
 
int main(void){
    HANDLE hMailSlot;
    DWORD bytesread;
    char buffer[512];
    if((hMailSlot=CreateMailslot(
        address,
        0,
        MAILSLOT_WAIT_FOREVER,
        NULL
    ))==INVALID_HANDLE_VALUE){
        printf("createmailslot error %d\n",GetLastError());
    }
    
    while(1){
        printf("received_message > ");
        ReadFile(
            hMailSlot,
            buffer,
            512,
            &bytesread,
            NULL
        );
        buffer[bytesread]='\x00';
        printf("%s (%d)\n",buffer,bytesread);
        if(!strcmp(buffer,"EXIT")){
            CloseHandle(hMailSlot);break;
        }
    }
}
 
 
cs

sender.c 같은 경우는, CreateFile 함수로 이미 만들어진 메일슬롯을 열고 내용을 쓴다.

receiver.c 는 CreateMailslot 함수로 메일슬롯을 만들고, 내용을 읽는다.

 

#윤성우 윈도우즈 시스템 프로그래밍 기반으로 작성되었습니다.