管道(Pipe) 管道是一种用于在进程间共享数据的机制,其实质是一段共享内存。Windows系统为这段共享的内存设计采用数据流I/0的方式来访问。由一个进程读、另一个进程写,类似于一个管道两端,因此这种进程间的通信方式称作“管道”。 管道分为匿名管道和命名管道。
1.匿名管道只能在父子进程间进行通信,不能在网络间通信,而且数据传输是单向的,只能一端写,另一端读。
2.命令管道可以在任意进程间通信,通信是双向的,任意一端都可读可写,但是在同一时间只能有一端读、一端写。
匿名管道: 创建管道: BOOL WINAPI CreatePipe( PHANDLE hReadPipe,//读取端句柄 PHANDLE hWritePipe,//输入端句柄 LPSECURITY_ATTRIBUTES lpPipeAttributes,//安全属性 DWORD nSize// 管道的缓冲区容量,NULL表示默认大小 ); 读取管道内数据: BOOL ReadFile( HANDLE hFile,//句柄,可以是标准输入输出流或文件或管道 LPVOID lpBuffer, //读取的数据写入缓冲区 DWORD nNumberOfBytesToRead,//指定读取的字节数 LPDWORD lpNumberOfBytesRead,//实际读取的字节数 LPOVERLAPPED lpOverlapped//用于异步操作,一般置为NULL ); 向管道写入数据: BOOL WriteFile( HANDLE hFile,//句柄,同上 LPCVOID lpBuffer,//指定待写入的数据 DWORD nNumberOfBytesToWrite,//写入的数据量 LPDWORD lpNumberOfBytesWritten,//实际要写的数据量 LPOVERLAPPED lpOverlapped//一般置为NULL );
为实现父子进程间的通信,需要对子进程的管道进行重定向: 我们知道创建子进程函数 CreateProcess中有一个参数STARUIINFO,默认情况下子进程的输入输出管道是标准输入输出流,可以通过下面的方法实现管道重定向: STARTUPINFO si; si.hStdInput = hPipeInputRead; //输入由标准输入 -> 从管道中读取 si.hStdOutput = hPipeOutputWrite; //输出由标准输出 -> 输出到管道
命名管道: 服务端代码流程: 1.创建命名管道: HANDLE WINAPI CreateNamedPipe( LPCTSTR lpName,//管道名 DWORD dwOpenMode,//管道打开方式 DWORD nMaxInstances,//表示该管道所能够创建的最大实例数量。 DWORD nOutBufferSize,//表示管道的输出缓冲区容量,为0表示使用默认大小。 DWORD nInBufferSize,//表示管道的输入缓冲区容量,为0表示使用默认大小。 DWORD nDefaultTimeOut,//表示管道的默认等待超时。 LPSECURITY_ATTRIBUTES lpSecurityAttributes//表示管道的安全属性。 ); 2.创建完成后等待连接: BOOL WINAPI ConnectNamedPipe( HANDLE hNamedPipe,//命名管道句柄 LPOVERLAPPED lpOverlapped//一般为NULL ); 3.读取客户端请求数据:ReadFile 4.向客户端回复数据:WriteFile 5.关闭链接: BOOL WINAPI DisconnectNamedPipe( HANDLE hNamedPipe ); 6.关闭管道:CloseHandle
客户端代码流程: 1 打开命名管道: HANDLE WINAPI CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ); 2 等待服务端相应: BOOL WINAPI WaitNamedPipe( LPCTSTR lpNamedPipeName,//命名管道名称 DWORD nTimeOut//等待时长 ); 3 切换管道为读模式: BOOL WINAPI SetNamedPipeHandleState( HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout ); 4 向服务端发送数据:WriteFile 5 读取服务端数据:ReadFile 6 关闭管道:CloseHandle
更多内容查看MSDN官网: https://msdn.microsoft.com/en-us/library/aa365781(v=vs.85).aspx