1. 程式人生 > 其它 >[Windows程序間通訊] 命名管道

[Windows程序間通訊] 命名管道

參考連結:

一個比較基本的示例:https://blog.csdn.net/caoshangpa/article/details/53199022

詳細的介紹及對命名管道安全的探討:https://blog.csdn.net/qq_36119192/article/details/112274131

命名管道雖然看起來和匿名管道類似,但是卻是大大的不同。以下列出幾點

1. 匿名管道只能用於父子程序間通訊,命名管道則無此限制,各個程序都可以通過名字獲取管道並通訊。但是因此比匿名管道要佔用更多資源,效率略低

2. 命名管道不僅可以跨程序,也可以跨機器,同時也存在安全問題。詳細可以參考開頭的連結

關於管道的內容可以寫出很多,這裡暫時先寫一個例程。思路與檔案對映類似,server端負責建立管道,cient端通過管道名字獲取管道並和server互動。

如果需要使用其他機器上的管道,那麼管道的名字需要加入server name。需要注意的是,命名管道受到windows ACL的控制,如果許可權不夠的話,是無法連線其他機器上的管道的。

下面是一個使用本地命名管道的示例

Server端

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

#define BUFFER_SIZE 1024
#define PIPE_NAME "\\\\.\\pipe\\test"

int main() {
    char buffer[BUFFER_SIZE] = { 0
}; DWORD readNum; auto hPipe = CreateNamedPipe( PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, 0, 0, 1000, NULL ); if (hPipe == INVALID_HANDLE_VALUE) { cout << "Create named pipe failed!
" << endl; return -1; } if (ConnectNamedPipe(hPipe, NULL) == FALSE) { cout << "Failed to connect pipe!" << endl; CloseHandle(hPipe); return -1; } cout << "Connected to pipe!" << endl; while (1) { if (ReadFile(hPipe, buffer, 1024, &readNum, NULL) == FALSE) { cout << "Failed to read data!" << endl; break; } buffer[readNum] = 0; cout << "Read data: " << buffer << endl; } cout << "Close pipe!" << endl; CloseHandle(hPipe); return 0; }

Client端

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

#define PIPE_NAME "\\\\.\\pipe\\test"
#define BUFFER_SIZE 1024

int main() {
    char buffer[BUFFER_SIZE] = { 0 };
    DWORD writeNum;

    if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == FALSE) {
        cout << "Wait named pipe failed!" << endl;
        return -1;
    }

    auto hPipe = CreateFile(
        PIPE_NAME, 
        GENERIC_READ | GENERIC_WRITE, 
        0, 
        NULL, 
        OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL, 
        NULL
    );
    if (hPipe == INVALID_HANDLE_VALUE) {
        cout << "Failed to create file!" << endl;
        return -1;
    }
    cout << "Connected to server!" << endl;

    while (1) {
        cin >> buffer;
        if (WriteFile(
            hPipe, 
            buffer, 
            strnlen_s(buffer, BUFFER_SIZE), 
            &writeNum, 
            NULL
        ) == FALSE) {
            cout << "write failed!" << endl;
            break;
        }
    }

    cout << "Close pipe!" << endl;
    CloseHandle(hPipe);

    return 0;
}