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