zoukankan      html  css  js  c++  java
  • 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 
    ";
    	WriteFile(hParentWrite, szBuffer, 15, NULL, 0);//使用writeFile操作管道,给cmd发送数据命令.
    	return 0;
    }
    
    

    1.5代码运行截图

  • 相关阅读:
    数据字典/动态性能视图
    参数管理
    expdp实现oracle远程服务器导出到本地
    jquery 操作单选按钮
    vs2012加载T4MVC模板
    Asp.net Mvc 过滤器执行顺序
    oracle版本及字符集查询
    ora-01658: 无法为表空间*****中的段创建 INITIAL 区
    SmtpClient发送邮件
    盒模型padding和margin对滚动条位置的影响
  • 原文地址:https://www.cnblogs.com/iBinary/p/10949198.html
Copyright © 2011-2022 走看看