管道的分类

管道其实际就是一段共享内存,只不过Windows规定需要使用I/O的形式类访问这块共享内存,管道可以分为匿名管道和命名管道。

  • 匿名管道就是没有名字的管道,其支持单向传输数据,如果需要双向传送数据就需要创建两条管道。而且其只支持具有父子关系的两个进程进行通信,不能在网络间进行通信。
  • 命名管道就是有名字的管道,其支持双向传输数据,因此一般还需要创建一条命名管道实现两个进程间的通讯。他的实现类似于我们了解的客户端/服务端。他能在任意进程间进行通讯。

匿名管道

typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength; //结构大小
LPVOID lpSecurityDescriptor; //安全属性(一般为NULL采用默认属性)
BOOL bInheritHandle; //管道句柄是否可继承
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;

匿名管道在创建前需要设置其安全描述符结构,此结构的bInheritHandle字段规定管道句柄是否可继承,也就是其此进程的子进程是否可以继承此管道句柄,如果不能继承那么子进程就无法使用此管道句柄进行管道数据的读写。

BOOL CreatePipe(
PHANDLE hReadPipe, //保存管道用来读数据的管道句柄的指针
PHANDLE hWritePipe, //保存管道用来写数据的管道句柄的指针
LPSECURITY_ATTRIBUTES lpPipeAttributes,
DWORD nSize
);

利用CreatePipe()创建匿名管道,nSize指定为管道缓冲区的大小,如果值为0就采用默认大小。

//伪代码
SECURITY_ATTRIBUTES.dwFlags = STARTF_USESTDHANDLES;
bInheritHandles = TRUE;

接着就是创建子进程,然后通过管道与此子进程进行通信。创建此子进程的STARTUPINFO结构的dwFlags字段要为STARTF_USESTDHANDLES这样改变子进程的标准输入输出才有效,否则无效。CreateProcess创建子进程时其第五个参数bInheritHandles要为TRUE,表示此进程创建的子进程可以继承本进程的句柄,这样本进程创建的管道句柄才能被子进程使用用来与本进程通信。

BOOL WriteFile(
HANDLE hFile, //对应写数据的管道句柄
LPCVOID lpBuffer, //保存写入数据的缓冲区
DWORD nNumberOfBytesToWrite, //写入数据的大小
LPDWORD lpNumberOfBytesWritten, //返回实际写入数据的大小
LPOVERLAPPED lpOverlapped //异步操作一般为NULL
); BOOL ReadFile(
HANDLE hFile, //对应读数据的管道句柄
LPVOID lpBuffer, //保存读取数据的缓冲区
DWORD nNumberOfBytesToRead, //读取数据缓冲区的大小
LPDWORD lpNumberOfBytesRead, //返回实际读取的数据大小
LPOVERLAPPED lpOverlapped ////异步操作一般为NULL
);

之后就通过WriteFile()和ReadFile()利用对应的管道句柄来通过管道与子进程进行通信。

HANDLE hMyWrite, hMyRead, hCmdWrite, hCmdRead;	

void _Init()
{
SECURITY_ATTRIBUTES as; //安全描述符结构
as.nLength = sizeof(SECURITY_ATTRIBUTES);
as.bInheritHandle = TRUE; //管道句柄可继承
as.lpSecurityDescriptor = NULL; //NULL表示使用默认的安全属性 CreatePipe(&hCmdRead, &hMyWrite, &as, 0); // my ----> cmd 管道
CreatePipe(&hMyRead, &hCmdWrite, &as, 0); // my <---- cmd 管道 STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi)); si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES; //意思是可以更改cmd的标准输入输出
si.hStdInput = hCmdRead; //子进程的标准输入为my ----> cmd管道的读管口
si.hStdOutput = hCmdWrite; //子进程的标准输入为my <---- cmd管道的写管口
si.hStdError = hCmdWrite; CreateProcess(TEXT("C:\\Windows\\System32\\cmd.exe"),
NULL,
NULL,
NULL,
TRUE, //句柄可继承
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi);
} int main(int argc, char* argv[])
{
_Init(); //初始化管道 char szWriteBuffer[MAX_PATH];
printf("%s", "请输入需要执行的cmd命令:");
scanf("%s", szWriteBuffer); WriteFile(hMyWrite, szWriteBuffer, sizeof(szWriteBuffer), NULL, NULL); //向管道中写数据
Sleep(1); DWORD dwSize; //每次从管道中读取数据的大小
char szBuffer1[MAX_PATH];
char szBuffer2[0x1000]; //存放最终的数据
while(1) //循环读取
{
memset(szBuffer1, 0, sizeof(szBuffer1));
ReadFile(hMyRead, szBuffer1, MAX_PATH, &dwSize, NULL); //从管道中读取数据
lstrcat(szBuffer2, szBuffer1);
if (dwSize != MAX_PATH)
break;
} printf("cmd的返回为:\n%s:", szBuffer2);
return 0;
}

上面的例子通过建立本进程与cmd进程之间的两条匿名管道进行数据的传递。

命名管道

利用命名管道进行两个进程间的通讯就类似于将两个进程一个当成服务端,一个当成客户端。

HANDLE CreateNamedPipeA(
LPCSTR lpName, //管道名称
DWORD dwOpenMode, //打开模式(单向还是双向)
DWORD dwPipeMode, //管道模式
DWORD nMaxInstances, //此管道最大的实例数
DWORD nOutBufferSize, //一般为0
DWORD nInBufferSize, //一般为0
DWORD nDefaultTimeOut, //表示管道的默认等待超时,NMPWAIT_WAIT_FOREVER表示一直等待
LPSECURITY_ATTRIBUTES lpSecurityAttributes //使用默认安全属性NULL
);

服务端创建命名管道返回管道句柄,管道的名称需要遵循入下格式\.\pipe\name,名字最长为256个字符。

BOOL ConnectNamedPipe(
HANDLE hNamedPipe, //命名管道句柄
LPOVERLAPPED lpOverlapped //一般为NULL
);

服务端创建完命名管道后就是等待客户端连接。

BOOL WaitNamedPipeA(
LPCSTR lpNamedPipeName, //命名管道名称
DWORD nTimeOut //等待时长,NMPWAIT_WAIT_FOREVER表示一直等待
);

客户端通过命名管道的名称连接服务端。

连接成功后通过CreateFile()打开命名管道并获得管道句柄,接着利用管道句柄通过ReadFile()和WriteFile()进行通讯。

Windows进程间通讯(IPC)----管道的更多相关文章

  1. High Performance Networking in Google Chrome 进程间通讯(IPC) 多进程资源加载

    小结: 1. 小文件存储于一个文件中: 在内部,磁盘缓存(disk cache)实现了它自己的一组数据结构, 它们被存储在一个单独的缓存目录里.其中有索引文件(在浏览器启动时加载到内存中),数据文件( ...

  2. Android AIDL 进行进程间通讯(IPC)

    编写AIDL文件时,需要注意: 1.接口名和aidl文件名相同. 2.接口和方法前不用加访问权限修饰符 (public.private.protected等,也不能用final.static). 3. ...

  3. QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开     本文地址:h ...

  4. Windows进程间通讯(IPC)----消息队列

    消息队列 windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息.这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建 ...

  5. Windows进程间通讯(IPC)----共享内存

    Windows中同一个EXE文件多次加载过程 Windows中EXE文件加载是基于内存映射文件的. 当EXE文件第一次被加载. 首先系统会先创建一个进程内核对象,并创建一个新的进程地址空间. 系统调用 ...

  6. Windows进程间通讯(IPC)----内存映射文件

    内存映射文件原理 内存映射文件是通过在虚拟地址空间中预留一块区域,然后通过从磁盘中已存在的文件为其调度物理存储器,访问此虚拟内存空间就相当于访问此磁盘文件了. 内存映射文件实现过程 HANDLE hF ...

  7. Windows进程间通讯(IPC)----WM_COPYDATA

    WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...

  8. 服务 远程服务 AIDL 进程间通讯 IPC

    Activity aidl接口文件 package com.bqt.aidlservice;  interface IBinderInterface {     /* 更改文件后缀为[.aidl]去掉 ...

  9. Windows进程间通讯(IPC)----信号量

    线程同步内核对象 操作系统进行进程间同步是利用信号量机制.对于windows系统而言,可以利用一些内核对象进行线程同步,因为这些内核对象可以命名并且属于系统内核,所以可以支持不同进程间的线程同步进而实 ...

随机推荐

  1. Python深入:setuptools进阶

    作者:gqtcgq 来源:CSDN 原文:https://blog.csdn.net/gqtcgq/article/details/49519685 Setuptools是Python Distuti ...

  2. SEO优化基础知识

    一.标点符号的重要性 很多人忽略了标点符号对爬虫的重要性,爬虫并不是对所有标点符号都爬取,下面列举几个对关键字分隔有帮助的符号. 1.1.逗号( , ) ==> 千万千万要使用英文的逗号,而不是 ...

  3. Java并发编程之同步/并发集合

    同步集合 Java中同步集合如下: Vector:基于数组的线程安全集合,扩容默认增加1倍(ArrayList50%) Stack:继承于Vector,基于动态数组实现的一个线程安全的栈 Hashta ...

  4. Kafka又出问题了!

    写在前面 估计运维年前没有祭拜服务器,Nginx的问题修复了,Kafka又不行了.今天,本来想再睡会,结果,电话又响了.还是运营,"喂,冰河,到公司了吗?赶紧看看服务器吧,又出问题了&quo ...

  5. 使用 Elastic 技术栈构建 Kubernetes全栈监控

    以下我们描述如何使用 Elastic 技术栈来为 Kubernetes 构建监控环境.可观测性的目标是为生产环境提供运维工具来检测服务不可用的情况(比如服务宕机.错误或者响应变慢等),并且保留一些可以 ...

  6. CVE-2010-3333-office RTF栈溢出漏洞分析

    0x00 前言 此漏洞是根据泉哥的<漏洞战争>来学习分析的,网上已有大量分析文章在此只是做一个独立的分析记录. 0x01 复现环境 操作系统-->windows7 x64 软件版本- ...

  7. java正则匹配${xxx} 排除单引号双引号内的内容,前提引号必须成对出现

    public static void main(String[] a) { String wpp = "select 1, ${mark} '``this is, `/message22` ...

  8. python基础(十七):函数

    在正式讲述函数之前,先给大家说明一点:编写函数就是"面向过程"的方式,编写类就是"面向对象"的方式.你如果不知道这是啥意思,至少别人提到这2个词你应该知道是在干 ...

  9. KubeEdge EdgeMesh设计原理

    EdgeMesh主要用来做边缘侧微服务的互访. ServiceMesh service mesh是一个服务网格的概念.在传统的架构里面都是通过像Dubbo来进行服务治理,服务治理的程序和我们应用程序强 ...

  10. kali 2019-4中文乱码解决方法

    1.更换阿里源 编辑源,apt-get update && apt-get upgrade && apt-get clean ,更新好源和更新软件 #阿里云deb ht ...