Windows程序设计学习笔记——匿名管道

管道是windows进程通信的一种方式,管道分为匿名管道(anonymous pipe)和命名管道,命名管道主要用于一对多的通信,匿名管道则用于父子进程的通信。匿名管道类似于一根单向的水管,在父子进程间传输字节流。

常用api如下:

创建管道:

BOOL WINAPI CreatePipe(
  __out     PHANDLE hReadPipe,    //管道读取句柄的指针
  __out     PHANDLE hWritePipe,    //管道写入句柄的指针
  __in_opt  LPSECURITY_ATTRIBUTES lpPipeAttributes,  //安全属性,需要设置否则子进程无法访问管道
  __in      DWORD nSize    //缓冲区大小
);
//成功返回非零值,失败返回0

从管道中读取数据:

BOOL WINAPI ReadFile(
  __in         HANDLE hFile,    //文件句柄(管道读取句柄)
  __out        LPVOID lpBuffer,    //缓冲区指针,缓冲区用于存放读取的数据
  __in         DWORD nNumberOfBytesToRead,    //所要读取的最大字节数
  __out_opt    LPDWORD lpNumberOfBytesRead,   //传出参数,记录成功读取的字节数
  __inout_opt  LPOVERLAPPED lpOverlapped    //可选参数,一般填null
);

//成功返回非零值,失败返回0

如果管道中没有数据流,那么readfile会阻塞,所以一般先要判断管道有无数据

//判断管道有无数据,也可用于读数据,但不会清除读过的数据
BOOL WINAPI PeekNamedPipe(
  __in       HANDLE hNamedPipe,    //管道句柄
  __out_opt  LPVOID lpBuffer,        //缓冲区指针(检查有无数据可填NULL)
  __in       DWORD nBufferSize,       //缓冲区大小(检查有无数据可填0)
  __out_opt  LPDWORD lpBytesRead,    //要读取的字节数,不读为NULL
  __out_opt  LPDWORD lpTotalBytesAvail,    //成功读取的字节数(最好要填这个参数不然函数可能失败)
  __out_opt  LPDWORD lpBytesLeftThisMessage    //管道剩余字节?(不读为空)
);

//返回非零值则成功,返回0则失败

向管道写入数据

BOOL WINAPI WriteFile(
  __in         HANDLE hFile,    
  __in         LPCVOID lpBuffer,
  __in         DWORD nNumberOfBytesToWrite,
  __out_opt    LPDWORD lpNumberOfBytesWritten,
  __inout_opt  LPOVERLAPPED lpOverlapped
);

//参数含义和返回值类似readfile

子进程获得管道句柄:

注意:父子进程使用管道通信时要设置子进程允许继承父进程句柄,否则子进程无法读取管道,此外在调用createprocess创建子进程时,STARTUPINFO结构体需要将管道read句柄设置为标准输入句柄,如图:


版权声明:本文为weixin_48088263原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。