Created
July 7, 2019 03:15
-
-
Save hyrious/67f243671456ce47f53371969dbcaba8 to your computer and use it in GitHub Desktop.
Windows IPC -- MailSlot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <stdio.h> | |
HANDLE hSlot; | |
LPTSTR Slot = TEXT("\\\\.\\mailslot\\meow"); | |
BOOL WINAPI MakeSlot(LPTSTR lpszSlotName) { | |
hSlot = CreateMailslot(lpszSlotName, 0, MAILSLOT_WAIT_FOREVER, 0); | |
if (hSlot == INVALID_HANDLE_VALUE) { | |
printf("CreateMailSlot failed with %d.\n", GetLastError()); | |
return FALSE; | |
} | |
return TRUE; | |
} | |
BOOL WINAPI GetSlot(LPTSTR lpszSlotName) { | |
hSlot = CreateFile(lpszSlotName, GENERIC_WRITE, FILE_SHARE_READ, | |
0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
if (hSlot == INVALID_HANDLE_VALUE) { | |
printf("CreateFile failed with %d.\n", GetLastError()); | |
return FALSE; | |
} | |
return TRUE; | |
} | |
BOOL ReadSlot(void) { | |
DWORD cbMessage, cMessage, cbRead; | |
BOOL fResult; | |
LPTSTR lpszBuffer; | |
TCHAR achID[80]; | |
DWORD cAllMessages; | |
HANDLE hEvent; | |
OVERLAPPED ov; | |
cbMessage = cMessage = cbRead = 0; | |
hEvent = CreateEvent(0, FALSE, FALSE, Slot); | |
ov.Offset = ov.OffsetHigh = 0; | |
ov.hEvent = hEvent; | |
fResult = GetMailslotInfo(hSlot, 0, &cbMessage, &cMessage, 0); | |
if (!fResult) { | |
printf("GetMailslotInfo failed with %d.\n", GetLastError()); | |
return FALSE; | |
} | |
if (cbMessage == MAILSLOT_NO_MESSAGE) { | |
printf("waiting...\n"); | |
return TRUE; | |
} | |
cAllMessages = cMessage; | |
while (cMessage) { | |
lpszBuffer = (LPTSTR) GlobalAlloc(GPTR, cbMessage); | |
if (lpszBuffer == NULL) | |
return FALSE; | |
lpszBuffer[0] = '\0'; | |
fResult = ReadFile(hSlot, lpszBuffer, cbMessage, &cbRead, &ov); | |
if (!fResult) { | |
printf("ReadFile failed with %d.\n", GetLastError()); | |
GlobalFree((HGLOBAL) lpszBuffer); | |
return FALSE; | |
} | |
printf(">> %s\n", lpszBuffer); | |
GlobalFree((HGLOBAL) lpszBuffer); | |
fResult = GetMailslotInfo(hSlot, 0, &cbMessage, &cMessage, 0); | |
if (!fResult) { | |
printf("GetMailslotInfo failed with %d.\n", GetLastError()); | |
return FALSE; | |
} | |
} | |
CloseHandle(hEvent); | |
return TRUE; | |
} | |
BOOL WriteSlot(HANDLE hSlot, LPTSTR lpszMessage) { | |
BOOL fResult; | |
DWORD cbWritten; | |
fResult = WriteFile(hSlot, lpszMessage, (lstrlen(lpszMessage) + 1) * sizeof(TCHAR), &cbWritten, 0); | |
if (!fResult) { | |
printf("WriteFile failed with %d.\n", GetLastError()); | |
return FALSE; | |
} | |
return TRUE; | |
} | |
int main(int argc, char **argv) { | |
if (argc < 2) { | |
if (!MakeSlot(Slot)) { | |
return EXIT_FAILURE; | |
} | |
printf("hSlot: %p\n", hSlot); | |
while (ReadSlot()) { | |
Sleep(1000); | |
} | |
} else { | |
if (!GetSlot(Slot)) { | |
return EXIT_FAILURE; | |
} | |
WriteSlot(hSlot, TEXT("Hello world! (1)")); | |
WriteSlot(hSlot, TEXT("Hello world! (2)")); | |
Sleep(5000); | |
WriteSlot(hSlot, TEXT("Hello world! (3 ... after 5s)")); | |
} | |
CloseHandle(hSlot); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
MailSlot is a one-way IPC method. To do duplex you should create two different slot.
This file is both server and client. Suppose we compiled it to a.exe.
Server:
Client:
If client starts before server, it will end with
WinError (2)
, meaning it can not find such slot.If server stops suddenly, the client will get
WinError (38)
, meaning it gotEOF
.If multiple servers start with the same slot name, the later ones will get
WinError (183)
, meaningErrno::EEXIST
.