目录
进程通信之一看就懂的匿名管道通信
一丶匿名管道
1.1 何为匿名管道
1.2 创建匿名管道需要注意的事项
1.3 创建匿名管道需要的步骤
1.4 代码例子
1.5 代码运行截图
进程通信之一看就懂的匿名管道通信
一丶匿名管道
1.1 何为匿名管道
匿名管道是用来父进程跟子进程通信的. 还有一种是命名管道. 不需要父子进程就可以进行通信的. 今天先说匿名管道的.
匿名管道. 就是父进程创建子进程. 读取子进程数据. 或者给子进程发送数据. 当然子进程也可以给父进程发送数据. 以及读取父进程发送过来的数据.
1.2 创建匿名管道需要注意的事项
创建匿名管道, 首先你要明白什么是管道. 管道你可以想象成一个管子.
我们通过这个管子发送数据.
如下图所示:
通过上图, 我们就知道其实创建了两个管道. 分别是父进程读取的管道. 以及
子进程读取的管道. 相应的. 子进程也可以对父进程读取的管道进行传输数据. 父进程就可以读取了.
这段话可能难以理解. 你可以这样想.
我父进程读取子进程使用第一个管道. 那么反正子进程写的话也是使用第一个管道. 因为子进程写. 我们父进程才能读.
1.3 创建匿名管道需要的步骤
首先你需要了解创建匿名管道的 API
- WINBASEAPI
- BOOL
- WINAPI
- CreatePipe(
- _Out_ PHANDLE hReadPipe,
- _Out_ PHANDLE hWritePipe,
- _In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes,
- _In_ DWORD nSize
- );
关于这个 API 很简单. 相比你过来看匿名管道. 说明你已经知道这个 API 了.
只不过不知道管道概念.(我猜的);
这个 API 很简单. 就是创建管道. 两个句柄. 读取句柄跟写入句柄.
我们需要创建两个管道.
还需要注意的是, 父进程创建子进程, 必须让父进程句柄可继承. 这个就是第三个属性. 安全属性描述符中给即可.
那么说一下创建步骤吧.
1. 创建一个安全属性描述符, 设置句柄可继承
2. 创建两个管道. 父读 -> 子写 子读 -> 父写的
3. 重定向输出, 将子进程的读 以及子进程的写重定向.
4. 创建子进程
5. 读取 \ 写入数据给子进程.
1.4 代码例子
- #include <stdio.h>
- #include <stdlib.h>
- #include <Windows.h>
- int main()
- {
- HANDLE hParentRead, hParentWrite, hChildRead, hChildWrite; // 创建 4 个句柄
- STARTUPINFO si = { 0 }; // 启动信息结构体
- si.cb = sizeof(si);
- PROCESS_INFORMATION pi = { 0 }; // 进程信息结构体
- DWORD dwWritedBytes = 0;
- DWORD dwReadedBytes = 0;
- DWORD dwBytesRead = 0;
- DWORD dwTotalBytesAvail = 0;
- DWORD dwBytesLeftThisMessage = 0;
- SECURITY_ATTRIBUTES sa = { 0 }; // 安全属性描述符
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = TRUE; // 设置句柄可继承
- // 创建管道 1. 父进程读 -> 子进程写入
- BOOL bRet = CreatePipe(&hParentRead,
- &hChildWrite,
- &sa,
- 0);
- // 创建管道 2. 子进程读 -> 父进程写.
- bRet = CreatePipe(&hChildRead,
- &hParentWrite,
- &sa,
- 0);
- // 这里将子进程写重定向到 stdout 中. 子进程读取重定向到 stdinput 中
- si.hStdInput = hChildRead;
- si.hStdOutput = hChildWrite;
- si.dwFlags = STARTF_USESTDHANDLES; // 设置窗口隐藏启动
- bRet = CreateProcess(NULL,
- "cmd.exe", // 创建 cmd 进程. 默认寻找 cmd 进程.
- NULL,
- NULL,
- TRUE,
- CREATE_NO_WINDOW,
- NULL,
- NULL,
- &si,
- &pi);
- char szBuffer[15] = "calc \n";
- WriteFile(hParentWrite, szBuffer, 15, NULL, 0);// 使用 writeFile 操作管道, 给 cmd 发送数据命令.
- return 0;
- }
1.5 代码运行截图
来源: https://www.cnblogs.com/iBinary/p/10949198.html