首页 > 系统相关 >Windows管道(Pipes)(一)

Windows管道(Pipes)(一)

时间:2024-09-26 11:24:11浏览次数:10  
标签:Windows 句柄 Pipes 写入 匿名 信息 管道 进程

    Windows操作系统提供了多种机制用于实现应用程序间的通信及数据的共享,比如剪贴板(Clipboard)、组件对象模型(COM)、数据复制(Data Copy)、动态数据交换(DDE)、文件映射(File Mapping)、邮件槽(Mailslots)、管道(Pipes)、远程过程调用(RPC)、Windows套接字(Windows Sockets)等,这些技术统称为进程间通信(IPC, Interprocess communication)技术。        现在我用两篇文章就其中的管道做一下简单介绍。管道,顾名思义,就是供信息流动的通道。它有两个端点,一个用于信息的写入,即写入端,另一个用于信息的读出,即读出端。根据管道内信息的流向,管道可被设定为单向(One-way)或双向(Two-way, 或 duplex)。单向管道允许位于写入端的进程写入信息,位于读出端的进程读出信息;双向管道允许每端的进程既可以写入信息,又可以读出信息。

        管道本质上是一段共享内存,供进程用作彼此互相通信的渠道。创建管道的进程被称作管道服务端(Pipe server),连接到现有管道的进程被称作管道客户端(Pipe client)。

        Windows环境的管道有两种,一种是匿名管道(Anonymous Pipes),即不需为其指定名称,另一种叫命名管道(Named pipes),在创建时需要遵循指定的规则为其指定名称。前者比后者占用系统资源少,但功能没有后者强大。

       本文只介绍匿名管道,命名管道在下一篇介绍。匿名管道(Anonymous pipes)匿名管道不需在创建时为其命名,不支持跨网络的通信,且只支持单向通信。若要用匿名管道实现进程间的双向通信,则要为每个方向单独创建一条匿名管道。

        要创建一个匿名管道需要调用CreatePipe()函数,它返回两个句柄(handle),读、写各一个。读句柄只能对管道进行读操作,写句柄只能对管道进行写操作。

        要使用匿名管道实现进程间通信,服务端进程必须通过某种方式将一个句柄传递到与之通信的另一个进程,至于传送哪一个,则要看所需要的信息传送方向了。这是一个与命名管道间的重要差异,通信双方都没有彼此知晓的名称,只能通过将一个句柄传递到对方的方式来建立联系了。

        基于这种建立联系的方式,匿名管道通常用于父、子进程之间的通信。父进程可借助继承机制很自然地将匿名管道的句柄传递给子进程,从而在父子进程间建立管道连接。要实现这一点,父进程要在几个关键节点扫除障碍。首先父进程要在创建匿名管道时将传入CreatePipe()函数的SECURITY_ATTRIBUTES结构中的bInheritHandle成员设置为TRUE,这使得CreatePipe()返回的句柄允许被子进程继承;另外父进程在调用CreateProcess()函数创建子进程时要明确要求子进程继承父进程的所有句柄。下面将整个流程描述一下。

        父进程通常是将标准输入(Standard input)、标准输出(Standard output)文件句柄重定向到匿名管道的读、写句柄来实现向子进程进行句柄传递的,父进程在子进程创建完毕后再将标准输入、输出文件句柄恢复原值。

        假如我们现在希望子进程向管道写入、父进程读取子进程写入的内容,那我们需要向子进程传递匿名管道的写句柄。父进程调用GetStdHandle()函数获取当前标准输出文件句柄,将其暂存以备后面恢复使用,然后调用SetStdHandle()将标准输出文件句柄设置为匿名管道的写入句柄。现在创建子进程,这样通过继承机制,子进程的标准输出文件句柄就是匿名管道的写句柄了。

        匿名管道的写句柄被子进程继承之后,父进程就不再需要该写句柄了,应调用CloseHandle()将其关闭,这一点很重要,后面会提到;而且还应及时用SetStdHandle()将已被重定向的标准输出文件句柄恢复为原值——稍早暂存的值。

        子进程继承了父进程的标准输出文件句柄,这实际上就是匿名管道的写句柄。子进程可调用GetStdHandle()来获取这一句柄,用WriteFile()函数向管道写入信息,父进程用ReadFile()从管道读取信息,从而实现了父子进程的信息交流。

        要从匿名管道读取信息,要用读句柄调用ReadFile()函数。如果管道为空ReadFile()会一直等待,直到写入端进程将信息写入管道才能返回。如果该管道的所有写入句柄都被关闭了,ReadFile()会返回0。这一点需特别注意,这就是为什么前面我们要求父进程在创建子进程后要用CloseHandle()关闭匿名管道的写句柄,因为如果不关闭,即使子进程关闭了自己的写句柄,父进程的ReadFile()也不会返回0——父进程还有一个写句柄未关闭!如果读取过程中出错ReadFile()也会返回,这时可用GetLastError()获得错误码。

        要向匿名管道写入信息,要用写句柄调用WriteFile()函数。WriteFile()要在将指定字节数的信息都写入匿名管道后才会返回,如果此时管道是满的且还有未写入的信息,WriteFile()会等,直到读取端读走信息,空出足够空间供WriteFile()完成写操作。当然,同ReadFile()一样,如果写入操作中途出错,WriteFile()也会返回,可用GetLastError()获得错误码。

        前面分析了父进程通过继承机制向子进程传递匿名管道的写句柄的过程,如果反过来,我们希望父进程向匿名管道写入信息,子进程从中读出信息,那么我们要向子进程传递读句柄,通过将父进程的标准输入文件句柄设置为读句柄,经过继承机制,子进程的标准输入文件句柄就是匿名管道的读句柄,就可以用GetStdHandle()获取用来读取信息了。这里需要注意的是一定要确保匿名管道的写句柄没有被继承到子进程,也是因为前面提到的原因,为了确保子进程的ReadFile()能在父进程关闭写句柄的时候能正确地返回0。

        最后再做两点说明:写入匿名管道的信息是以字节流的形式写入的,读取进程无法从中分辨出哪些信息是由哪一次写操作写入的,除非读写双方事先约定如何来判断每次写入信息的结束方式。这又是一个匿名管道与命名管道相比比较逊色的地方。其实匿名管道的应用不仅限于父子进程间的通信,也可用于不相关进程间的通信,只要能将一个句柄正确地传递给对方就行,比如通过某种进程间通信的方式。

        下一篇介绍命名管道。

标签:Windows,句柄,Pipes,写入,匿名,信息,管道,进程
From: https://blog.51cto.com/u_2999564/12118078

相关文章

  • windows hosts 你没有权限在此位置中保存文件 请与管理员联系
    一、问题现象administrator管理管理员打开hosts没有权限,修改hosts内容后没有权限保存,提示C:\Windows\System32\drivers\etc\hosts你没有去权限在此位置中保存文件。二、解决问题右键点击hosts---属性---安全---高级---更改权限点击添加进行新增权限设置选则主体---检查名称框输入用......
  • Centos6搭建Samba服务并使用Windows挂载
    一、安装相关软件[root@mail~]#yuminstallsambasamba-client-y#安装相关软件二、配置匿名访问[root@mail~]#cd/etc/samba/[root@mailsamba]#cpsmb.confsmb.conf-bak#备份配置文件[root@mailsamba]#vimsmb.conf[global]#全局配置......
  • 将Java编译的 .jar文件做成windows服务 实现开机自启动
    将Java编译的.jar文件做成windows服务实现开机自启动1、将windows服务制作工具(在网上下载) 复制到 jar程序目录下,并改名为 install.exe2、新建xml文件,将文件名命名为 install.xml3、将下面内容复制到xml文件中,启动模式为自动启动Automatic   修改jar文件路径......
  • Windows系统的Tomcat日志路径配置
    文章目录引言IWindows系统的Tomcat日志路径配置配置常规日志路径访问日志路径配置,修改server.xmlII日志文件切割:以分隔割tomcat的catalina.out文件为例子通过Linux系统自带的切割工具logrotate来进行切割引言需求:C盘空间不足,处理日志文件,tomcat......
  • Windows系统修改Tomcat虚拟机内存参数
    文章目录I修改Tomcat虚拟机内存参数基于tomcat管理程序进行配置基于setenv文件进行配置II查看服务器状态/manager/status查看服务器状态manager/jmxproxy查询Tomcat指标I修改Tomcat虚拟机内存参数基于tomcat管理程序进行配置查看堆内存分配情......
  • Windows使用使用旧版有道云客户端导出所有笔记
    使用旧版有道云笔记客户端导出所有笔记最近在复习之前的笔记,边复习边整理,准备把之前在有道云笔记的文档全部整理导出,原因你懂得(有道云笔记是越做越烂了!!!),有道云笔记新版本的客户端不支持导出所有笔记。依稀记得老版本好像是支持全部导出的,我找到了2年前保存的旧版本的客户......
  • windows server 怎么 禁用 SWEET32 密码组
    在WindowsServer上禁用SWEET32密码组可以按照以下步骤进行操作:一、确定使用的加密协议首先,确定你的WindowsServer正在使用的加密协议是SSL/TLS还是其他协议。如果是SSL/TLS,通常是通过InternetInformationServices(IIS)或其他网络服务来实现的。二、使用注册......
  • Bypass ESU v12 ESU v12 指的是 Microsoft 的扩展安全更新(Extended Security Updates
    BypassESUv12  ESUv12指的是Microsoft的扩展安全更新(ExtendedSecurityUpdates),主要用于支持未升级到新版本的Windows7用户。绕过ESUv12通常涉及寻找方法以在不支付订阅费用的情况下继续接收安全更新。这可能会违反许可协议,因此不建议采取此类措施。ESUv12绕过......
  • Windows系统的Mamba环境配置详细教程(状态空间模型)
    目录一、Win系统安装详细教程1、准备2、安装Triton1)下载后,通过cmd命令符进入到该文件的文件夹路径:2)安装Triton2、安装causal_conv1d3、安装mamba_ssm二、检查是否成功运行一、Win系统安装详细教程安装系统要求:cuda11.8、python3.101、准备根据下面的步骤,创建虚拟......
  • Windows Server 安装MySQL教程(图文)
    本篇教程,在服务器WindowsServer2016(中文版)上安装MySQL8.0,并记录详细的安装步骤。1、下载安装包在mysql官网上下载安装包下载地址:https://dev.mysql.com/downloads/installer/2、安装步骤下载之后,双击运行mysql-installer-community-8.0.39.0.msi如果双击无反应,那么需要安装一......