Windows進程通信之一看就懂的匿名管道通信


進程通信之一看就懂的匿名管道通信

一丶匿名管道

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代碼運行截圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM