• 网络学院
  • IT资讯
  • 操作系统
  • 网络技术
  • 软件应用
  • 办公软件
  • 编程技术
  • 网站架设
  • 数据库类
  • 平面设计
  • 多媒体类
  • 游戏资讯
  • 教学论文
  • 认证考试
VC++下对匿名管道的编程实现
  站点:
  • 首 页
  • 最新软件
  • 文章教程
  • 国内软件
  • 国外软件
  • 绿色软件
  • 源码下载
  • 字体下载
VC++下对匿名管道的编程实现
软件发布 VC++下对匿名管道的编程实现
网络软件 系统工具 应用软件 联络聊天 图形图像 多媒体类 行业软件 游戏娱乐 编程开发 安全相关 教育教学 数码软件 绿软下载
热门软件: QQ 瑞星 pplive e话通 木马克星 千千静听 office2000 五笔字根 Photoshop 视频分割
返回文章教程首页 >> 编程技术 >> VC教程 >> VC++下对匿名管道的编程实现

VC++下对匿名管道的编程实现

添加时间: 2006-2-11 0:46:34  作者: VC教程  阅读次数:769   来源: http://www.d9soft.com

          概述

  管道(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;

  }

 

上下文章:

 

上一篇文章: 利用VC#开发一个媒体播放器 下一篇文章: VC++实例:晚捆绑的实现过程

相关文章:

  • Word设计师欲重返太空 明春或能实现(图)
  • NET 拖动无边框窗体编程实例
  • 自学.NET之路-C#编程之基础总结
  • 编程实例 使用C#的BitmapData
  • 应用Privoxy让Chrome实现广告过滤

相关软件:

  • 编程傻瓜--逗死汇编 V1.6
  • KS线切割编程系统 V2.18
  • 软件编程伴侣 4.0
  • 易语言汉语编程环境 V4.10
  • 超想中文汇编编程学习系统(中英对照版) V3.0
  • VFP完全控制大、中、小型数据库编程接口 V12.0

 

快速导航

  • 网络学院
  • 精品汇聚
  • 字体下载
  • 教程下载
  • ASP源码
  • PHP源码
  • Net源码
  • JSP 源码

编程技术分类导航

  • ASP & ASP.NET教程
  • PHP教程
  • JSP教程
  • C/C++教程
  • VB & VB.NET教程
  • VC教程
  • Delphi教程
  • BCB教程
  • VFP教程
  • PB教程
  • JAVA教程
  • XML教程
  • C#教程
  • CGI教程

本类经典文章推荐

  • VC++之Button控件
  • VC++之Static Box控件
  • VC++之Edit Box控件
  • VC++之Static Box控件
  • VC++之Edit Box控件
  • VC++之Scroll Bar
  • VC++之Scroll Bar
  • VC++之List Box/Check List Box控...
  • VC++ Combo Box/Combo Box Ex控件
  • VC++ List Ctrl控件

VC教程阅读排行

  • VC++之List Box/Check List Box控...
  • VC++ List Ctrl控件
  • VC++ Combo Box/Combo Box Ex控件
  • VC++之Button控件
  • VC++之Tab Ctrl控件
  • VC++之Edit Box控件
  • VC++之Edit Box控件
  • VC遍历整个目录树查找文件
  • VC++之Scroll Bar
  • VC使用ActiveX控件常见问题

编程技术阅读总排行

  • VB入门教程之一
  • Java连接数据库实例
  • VC++之List Box/Check List Box控...
  • 第二章 PowerBuilder 入门之创建新...
  • VC++ List Ctrl控件
  • 第一章 什么是PowerBuilder
  • VC++ Combo Box/Combo Box Ex控件
  • 学C++不得不看的一篇文章
  • VB入门教程之二
  • VC++之Button控件

广告位置

字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 回到顶部

关于我们 | 版权声明 | 免责条款 | 广告联系 | 软件发布 | 下载帮助 | 下载排行 | 网站地图 | 特别鸣谢 | 友情连接

copyright; 2005-2008 D9soft.com 第九软件网 版权所有