1. 程式人生 > 其它 >[Windows程序間通訊]郵件槽(mail slot)

[Windows程序間通訊]郵件槽(mail slot)

郵件槽(mailslot)是一種不可靠的、可廣播的IPC方式。它具有以下特點

1. 不侷限於本機程序間通訊,可以跨裝置

2. 使用無需確認的報文在網路上傳輸,因此不可靠,可能丟失

3. 能傳輸的訊息大小最大為424位元組

4. 可以進行廣播

命名管道也是一種可以跨裝置的程序間通訊方式,而且可以保證資料能被正確接收,郵件槽雖然不可靠,但是可以支援廣播。在同一個域內,如果有多個裝置擁有同一個郵件槽名字的控制代碼,那麼當向這個郵件槽傳送訊息時,所有的裝置都能接收到訊息。需要注意的是,同一個裝置上,只能有一個server程序擁有同名郵件槽,比如,如果同一個裝置上有兩個程序想同時用一個郵件槽收到訊息則不行。

關於郵件槽的命名:

1. 本機使用:"\\\\.\\mailslot\\[path\\]name"

2. 域內使用:"\\\\DomainName\\mailslot\\[path\\]name"

具體請參考微軟官方文件:Mailslot Names - Win32 apps | Microsoft Docs

下面是本地程式使用郵件槽的例程:

Server

#include <windows.h>
#include <iostream>
using namespace std;

#define MAILSLOT_NAME "\\\\.\\mailslot\\MyMailslot"
#define
BUFFER_SIZE 0x100 int main() { char buffer[BUFFER_SIZE] = { 0 }; DWORD dwLen = 0; auto hMailslot = CreateMailslot( MAILSLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, NULL); if (hMailslot == INVALID_HANDLE_VALUE) { if (hMailslot == INVALID_HANDLE_VALUE) { cout
<< "Create mailslot failed." << endl; return -1; } } while (true) { auto book = ReadFile(hMailslot, buffer, BUFFER_SIZE, &dwLen, NULL); if (!strcmp(buffer, "quit")) { break; } cout << "Client: " << buffer << endl; } CloseHandle(hMailslot); return 0; }

Client

#include <windows.h>
#include <iostream>
using namespace std;

#define MAILSLOT_NAME "\\\\.\\mailslot\\MyMailslot"
#define BUFFER_SIZE 0x100

int main() {
    char buffer[BUFFER_SIZE] = {0};
    DWORD dwLen = 0;
    auto hMailslot = CreateFile(
        MAILSLOT_NAME, 
        GENERIC_WRITE, 
        FILE_SHARE_READ, 
        NULL, 
        CREATE_ALWAYS, 
        FILE_ATTRIBUTE_NORMAL, 
        NULL);
    if (hMailslot == INVALID_HANDLE_VALUE) {
        cout << "Can't create file." << endl;
        return -1;
    }

    while (true) {
        cin >> buffer;
        if (!strcmp(buffer, "quit")) {
            WriteFile(hMailslot, buffer, BUFFER_SIZE, &dwLen, NULL);
            break;
        }

        auto ret = WriteFile(hMailslot, buffer, BUFFER_SIZE, &dwLen, NULL);
        if (!ret) {
            CloseHandle(hMailslot);
            return -1;
        }
    }

    CloseHandle(hMailslot);

    return 0;
}