進程通信之一看就懂的匿名管道通信
一丶匿名管道
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;
}