Mail Slot은 프로세스간에 데이터를 주고받기 위한 방식중 하나입니다.
프로세스는 기본적으로 자신에게 할당된 메모리를 공유할 수 없기 때문에 여러가지 방법으로 데이터를 주고 받습니다.
Mail Slot은 파일에 데이터를 적어 놓고 다른 프로세스들이 해당 파일에 접근해서 데이터를 읽어오도록 합니다.
따라서 파일을 읽을 수 있는 함수인 ReadFile() 함수와 데이터를 작성할 수 있는 WriteFile() 함수가 사용됩니다.
MailSlot의 특징은 다음과 같습니다.
1. 단방향 통신이다.
CreateMailslot() 함수로 보낼 메일 슬롯의 파일을 생성하고 WriteFile()함수를 통해 입력을 하게되고
CreateFile() 함수를 통해 파일을 열어 해당 내용을 읽어올 수 있는 ReadFile()함수를 사용하게 됩니다.
하지만 파일을 읽는 특성상 while(1)에 입력값이 있는지 혹은 읽을 값이 있는지를 계속해서 확인해야 합니다.
따라서 양방향 통신을 하게 하려면 CreateMailslot()과 CreateFile()함수를 동시에 만들어야 하죠.
또한 자연스럽게 작동하게 하려면 이 둘을 쓰레드 형태로 분리시켜야 합니다.
2. 브로드케스트를 한다.
Mailslot특성상 하나의 파일에 데이터를 입력하고 다른 프로세스들은 해당 파일을 참조해 읽기 때문에
쓰는 프로세스와 읽는 프로세스가 나뉘어져 있습니다. 여기서 다른 프로세스가 ReadFile()로 데이터를 읽으면
다른 프로세스들이 못읽는 것이아니라 Mailslot을 참조하고 있는 모든 프로세스들이 동일한 내용을 받아서 읽을 수 있기 때문에
브로드케스트를 한다고 말합니다.
CreateMailslot()은 다음과 같이 구성되어 있습니다.
HANDLE CreateMailslot(
LPCTSTR lpName,
DWORD nMaxMessageSize,
DWORD lReadTimeout
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
Colored by Color Scripter
cs
CreateMailslot()함수로 mailslot을 만들게 되면 다음과 같은 상태가 됩니다.
"지정된 경로의 mailslot파일에 접근할 준비가 완료됐습니다."
그럼 해당 경로로 가서 mailslot파일을 읽어와야 합니다.
파일을 읽어오는 것이기 때문에 ReadFile()함수가 사용됩니다.
ReadFile()
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
CreateMailslot()함수를 통해 데이터를 읽을 준비가 완료되면 해당 파일에 데이터를 보내는 작업이 필요합니다.
해당 작업은 CreateFile() 함수와 WriteFile() 함수를 통해 작업이 가능합니다.
CreateFile() 함수는 다음과 같이 정의되어 있습니다.
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
dwDesiredAccess(ReMarks) 파일 및 디렉터리 접근 권한
GENERIC_ALL 가능한 모든 엑세스 권한 허용 GENERIC_EXECUTE 엑세스 실행 권한 GENERIC_WRITE 쓰기 권한 GENERIC_READ 읽기 권한 MAXIMUM_ALLOWED 최대한 많은 권한 허용 DELETE 삭제 권한 READ_CONTROL 보안, DACL 디스크립터를 읽을 수 있는 권한 WRITE_DAC DACL에 대한 쓰기 권한 WRITE_OWNER 소유자에게 쓰기 권한 SYNCHRONIZE 엑세스 동기화 참고 : https://docs.microsoft.com/ko-kr/windows/win32/secauthz/access-mask
dwShareMode 파일 및 디렉터리 공유 모드
0 다른 프로세스가 파일 또는 디렉토리에 대한 읽기, 쓰기, 삭제를 못하게 막는다. FILE_SHARE_DELETE 삭제 요청을 허용(이름 바꾸는 작업도 포함) FILE_SHARE_READ 읽기 요청을 허용 FILE_SHARE_WRITE 쓰기 요청을 허용 참고 : https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
lpSecurityAttributes
SECURITY_ATTRIBUTES 구조에 대한 포인터 입니다.
NULL 전달시 return된 핸들 값은 상속될 수 없으며 기본 보안설정이 됩니다.
SECURITY_ATTRIBUTES
typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
nLength 구조체의 크기 설정 lpSecurityDescriptor 엑세스 토큰에 대한 설정, , NULL입력 시 기본 보안설정 bInheritHandle 반환된 핸들을 상속할지 여부 결정. 참고 : https://docs.microsoft.com/ko-kr/previous-versions/windows/desktop/legacy/aa379560(v=vs.85)
dwCreationDisposition
CREATE_ALWAYS 항상 새 파일을 만듦 CREATE_NEW 파일이 존재하지 않는 경우에만 새 파일 만듦 OPEN_ALWAYS 항상 파일을 연다. OPEN_EXISTING 파일 또는 장치가 있는 경우에만 연다. TRUNCATE_EXISTING 파일이 존재한다면 기존 내용을 모두 지운 후 연다.
dwFlagsAndAttributes
파일에 대한 속성값 정의
FILE_ATTRIBUTE_ARCHIVE 해당 파일을 보관(쓰기)할 때 사용 FILE_ATTRIBUTE_ENCRYPTED 파일이나 폴더를 암호화로 지정합니다. 파일의 경우 모든 내용을 암호화하며 폴더의 경우 새로 만들어지는 파일을 암호화합니다. FILE_ATTRIBUTE_HIDDEN 파일을 숨김으로 지정 FILE_ATTRIBUTE_NORMAL 파일에 대한 속성을 지정하지 않는다. FILE_ATTRIBUTE_OFFLINE 연결되지 않은 저장 장치에 있어 즉시 사용할 수 없는 파일 FILE_ATTRIBUTE_READONLY 읽기 전용파일로 설정 FILE_ATTRIBUTE_SYSTEM 시스템 파일로 설정 FILE_ATTRIBUTE_TEMPORARY 임시 파일로 지정
TemplateFile
GENERIC_READ 엑세스 권한을 가진 템플릿 파일의 유효한 핸들입니다.
생성된 파일에 대한 속성및 확장을 제공하는 템플릿입니다.
사용하지 않을 경우 NULL 값을 사용합니다.
WirteFile()
WriteFile은 파일에 데이터를 쓰개해주는 함수입니다.
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
hFile | 핸들을 지정합니다. 즉, 파일에 데이터를 입력할 해당 핸들을 지정합니다. |
lpBuffer | 전송할 데이터를 저장할 수 있는 버퍼입력 |
nNumberOfBytesToWrite | 전송할 데이터의 크기를 지정 |
lpNumberOfBytesWritten | 데이터를 보낸 후 보낸 길이를 저장 |
lpOverlapped | 비동기 입출력을 사용할 경우 OVERLAPPED 구조체를 정의해 사용하고 그렇지 않을 경우엔 NULL 입력. |
다음은 예제 입니다.
mailslot-sender
//visual studio 2017
//mailslot-sender
#include <iostream>
#include <Windows.h>
using namespace std;
#define SLOT_NAME "\\\\.\\mailslot\\mailbox"
int main(void) {
HANDLE mail_slot;
char buffer[1024];
unsigned long len;
mail_slot = CreateFile(
SLOT_NAME,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
while (1) {
cin >> buffer;
WriteFile(mail_slot, buffer, sizeof(buffer), &len, NULL);
}
CloseHandle(mail_slot);
return 0;
}
mailslot-recive
//visual studio 2017
//mailslot-recive
#include <Windows.h>
#include <iostream>
using namespace std;
#define SLOT_NAME "\\\\.\\mailslot\\mailbox"
int main(void) {
HANDLE mail_slot;
char buffer[1024];
unsigned long len;
mail_slot = CreateMailslot(
SLOT_NAME,
0,
MAILSLOT_WAIT_FOREVER,
NULL
);
while (1) {
ReadFile(mail_slot, buffer, sizeof(buffer), &len, NULL);
cout << buffer << endl;
}
CloseHandle(mail_slot);
return 0;
}
'프로그래밍 > 운영체제' 카테고리의 다른 글
C/C++ 뇌를 자극하는 윈도우 운영체제 프로젝트 2. (0) | 2019.12.29 |
---|---|
C/C++ 프로세스 생성하기. (0) | 2019.12.29 |
c/c++ TCHAR 정리. (1) | 2019.12.29 |
유니코드와 아스키코드(SBCS, MBCS, WBCS) (0) | 2019.12.11 |
댓글