[Windows程序間通訊] 命名管道
阿新 • • 發佈:2022-05-20
參考連結:
一個比較基本的示例: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; }