CreatePipe匿名管道通信

CreatePipe匿名管道通信管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。匿名管道(AnonymousPipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。      匿名管道实施细则      匿名管道由Cre

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。匿名管道(Anonymous Pipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。
  
    匿名管道实施细则
  
    匿名管道由CreatePipe()函数创建,该函数在创建匿名管道的同时返回两个句柄:管道读句柄和管道写句柄。CreatePipe()的函数原型为:
  
  BOOL CreatePipe(PHANDLE hReadPipe, // 指向读句柄的指针
   PHANDLE hWritePipe, // 指向写句柄的指针
   LPSECURITY_ATTRIBUTES lpPipeAttributes, // 指向安全属性的指针
   DWORD nSize // 管道大小
  ); 
  
    通过hReadPipe和hWritePipe所指向的句柄可分别以只读、只写的方式去访问管道。在使用匿名管道通信时,服务器进程必须将其中的一个句柄传送给客户机进程。句柄的传递多通过继承来完成,服务器进程也允许这些句柄为子进程所继承。除此之外,进程也可以通过诸如DDE或共享内存等形式的进程间通信将句柄发送给与其不相关联的进程。 
  
    在调用CreatePipe()函数时,如果管道服务器将lpPipeAttributes 指向的SECURITY_ATTRIBUTES数据结构的数据成员bInheritHandle设置为TRUE,那么CreatePipe()创建的管道读、写句柄将会被继承。管道服务器可调用DuplicateHandle()函数改变管道句柄的继承。管道服务器可以为一个可继承的管道句柄创建一个不可继承的副本或是为一个不可继承的管道句柄创建一个可继承的副本。CreateProcess()函数还可以使管道服务器有能力决定子进程对其可继承句柄是全部继承还是不继承。
  
    在生成子进程之前,父进程首先调用Win32 API SetStdHandle()使子进程、父进程可共用标准输入、标准输出和标准错误句柄。当父进程向子进程发送数据时,用SetStdHandle()将管道的读句柄赋予标准输入句柄;在从子进程接收数据时,则用SetStdHandle()将管道的写句柄赋予标准输出(或标准错误)句柄。然后,父进程可以调用进程创建函数CreateProcess()生成子进程。如果父进程要发送数据到子进程,父进程可调用WriteFile()将数据写入到管道(传递管道写句柄给函数),子进程则调用GetStdHandle()取得管道的读句柄,将该句柄传入ReadFile()后从管道读取数据。
  
    如果是父进程从子进程读取数据,那么由子进程调用GetStdHandle()取得管道的写入句柄,并调用WriteFile()将数据写入到管道。然后,父进程调用ReadFile()从管道读取出数据(传递管道读句柄给函数)。
  
    在用WriteFile()函数向管道写入数据时,只有在向管道写完指定字节的数据后或是在有错误发生时函数才会返回。如管道缓冲已满而数据还没有写完,WriteFile()将要等到另一进程对管道中数据读取以释放出更多可用空间后才能够返回。管道服务器在调用CreatePipe()创建管道时以参数nSize对管道的缓冲大小作了设定。
  
    匿名管道并不支持异步读、写操作,这也就意味着不能在匿名管道中使用ReadFileEx()和WriteFileEx(),而且ReadFile()和WriteFile()中的lpOverLapped参数也将被忽略。匿名管道将在读、写句柄都被关闭后退出,也可以在进程中调用CloseHandle()函数来关闭此句柄
  
  
  
  /
  匿名管道程序示例
  
    总的来说,匿名管道程序是比较简单的。在下面将要给出的程序示例中,将由父进程(管道服务器)创建一个子进程(管道客户机),子进程回见个其全部的标准输出发送到匿名管道中,父进程再从管道读取数据,一直到子进程关闭管道的写句柄。其中,匿名管道服务器程序的实现清单如下:
  
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  char ReadBuf[100];
  DWORD ReadNum;
  HANDLE hRead; // 管道读句柄
  HANDLE hWrite; // 管道写句柄
  BOOL bRet = CreatePipe(&hRead, &hWrite, NULL, 0); // 创建匿名管道
  if (bRet == TRUE)
   printf(“成功创建匿名管道!\n”);
  else
   printf(“创建匿名管道失败,错误代码:%d\n”, GetLastError());
   // 得到本进程的当前标准输出
   HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);
   // 设置标准输出到匿名管道
   SetStdHandle(STD_OUTPUT_HANDLE, hWrite);
   GetStartupInfo(&si); // 获取本进程的STARTUPINFO结构信息
   bRet = CreateProcess(NULL, “Client.exe”, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); // 创建子进程
   SetStdHandle(STD_OUTPUT_HANDLE, hTemp); // 恢复本进程的标准输出
   if (bRet == TRUE) // 输入信息
    printf(“成功创建子进程!\n”);
   else
    printf(“创建子进程失败,错误代码:%d\n”, GetLastError());
    CloseHandle(hWrite); // 关闭写句柄
    // 读管道直至管道关闭
    while (ReadFile(hRead, ReadBuf, 100, &ReadNum, NULL))
    {

     ReadBuf[ReadNum] = ‘\0’;
     printf(“从管道[%s]读取%d字节数据\n”, ReadBuf, ReadNum);
    }
    if (GetLastError() == ERROR_BROKEN_PIPE) // 输出信息
     printf(“管道被子进程关闭\n”);
    else
     printf(“读数据错误,错误代码:%d\n”, GetLastError()); 
  
    在本示例中,将当前进程的标准输出设置为使用匿名管道,再创建子进程,子进程将继承父进程的标准输出,然后再将父进程的标准输出恢复为其初始状态。于是父进程便可从管道读取数据,直到有错误发生或关闭管道写入端的所有句柄。创建的子进程只是向标准输出和标准错误发送一些文本信息,其中发送给标准输出的文本将重定向输出到管道,发送给标准错误的文本将不改变输出。下面给出子进程的实现代码:
  
  int main(int argc, char* argv[])
  {

   for (int i = 0; i < 100; i++) // 发送一些数据到标准输出和标准错误
   {

    printf(“i = %d\n”, i); // 打印提示
    cout << “标准输出:” << i << endl; // 打印到标准输出
    cerr << “标准错误:” << i << endl; // 打印到标准错误
   }
   return 0;

  } 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/159390.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 判断处理器是大端还是小端_网络字节序是大端还是小端

    判断处理器是大端还是小端_网络字节序是大端还是小端最近用杰理AC6966B调试博通的BK9527U段发射芯片,一直没调通,经过测试IIC通讯是通,硬件还是好的,但是怎么都调不到与接收端成功连接。最后咨询原厂得知提供的demo代码是大端编码模式的MCU代码,如果是小端模式,在部分写寄存器操作的过程中,如果直接传指针数据会反掉。杰理的MCU应该是小端模式,平时写代码用memcpy函数操作指针赋值最后得到的结果都是低位在前。为了进一步验证,网上找了一段代码验证,原理跟memcpy给指针赋值是类似的,最后成功验证到杰理的AC,AD系列都是小端模式:

  • 4.vue 的双向绑定的原理是什么?_Vue双向绑定原理

    4.vue 的双向绑定的原理是什么?_Vue双向绑定原理Vue双向绑定原理及问题剖析,快速搞懂Vue双向绑定~

    2022年10月17日
  • 推荐一个 curl 命令转化为PHP代码的网站&&在线发起执行 curl 请求的网站

    推荐一个 curl 命令转化为PHP代码的网站&&在线发起执行 curl 请求的网站

  • TiDB 在银行核心金融领域的研究与两地三中心实践

    TiDB 在银行核心金融领域的研究与两地三中心实践作者介绍:于振华,北京银行软件开发部资深架构师,长期从事银行核心系统研发、规划,参与过多个核心信息系统建设工作,包括一、二代支付系统、第四代银行核心系统建设、分布式核心系统建设等企业级项目工作。当前主要研发方向集中在构建先进、高效、面向OLTP的银行交易系统,提升银行信息系统服务能力。本文整理自于振华老师在TiDBDevCon2019上的演讲实录,演讲主题为《TiDB在…

  • EXCEL利用VBA把汉字转拼音(李晓锋版)20180828更新「建议收藏」

    EXCEL利用VBA把汉字转拼音(李晓锋版)20180828更新「建议收藏」EXCEL利用VBA把汉字转换为拼音,现在网络中广泛传播的代码存在错误,经过本人严格校对,把修正后的代码分享给大家。代码更新20180607:根据评论,之前的代码的确是无法翻译“瑜琦钰奕”这四个字的拼音,原因是他们的码值没有包含在代码中,现在已添加相应代码。谢谢 likewam  的评论。另外,希望大家能把自己使用过程中发现的所有不能转换的汉字都添加到评论,让我们一起来完善这部分代…

  • 如何关闭笔记本小键盘_笔记本电脑怎么关键盘灯光

    如何关闭笔记本小键盘_笔记本电脑怎么关键盘灯光2016-12-0815:00:40您使用下面两个方法,都可以用来关闭触摸板:(1)请您“双击”触摸板左上角位置的小圆点,当指示灯为橙色时,表示触摸板关闭。(2)或者,请您点击开始—控制面板—鼠标—装置设…2017-01-0116:08:43笔记本的小键盘区一般是在右手边的字母区,是蓝色字的。和台式机一样,笔记本也是有一个NUMLOCK键的。就是小键盘区的开关(一般也是蓝…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号