[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#include 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#include 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; }