匿名管道 双向通信 需要两个
2013-05-07 01:52 Scott Guthrie Liu 阅读(426) 评论(0) 编辑 收藏 举报http://www.cppblog.com/returnnull/archive/2007/05/11/23855.html
http://www.cppblog.com/ice197983/articles/4425.html
http://blog.163.com/kksunshine@yeah/blog/static/118612388201121154017976/
http://blog.163.com/tangmin927@126/blog/static/31537494200922043055553/
http://www.cnblogs.com/BoyXiao/archive/2011/01/01/1923828.html
View Code
#include <Windows.h> int main(int argc, char* argv[]) { HANDLE hWrite;//管道的写入句柄 HANDLE hRead; //管道的读取句柄 HANDLE hWrite2;//管道的写入句柄 HANDLE hRead2; //管道的读取句柄 SECURITY_ATTRIBUTES sa; //总共就三个参数 sa.bInheritHandle=TRUE; //表示可被子进程所继承 sa.lpSecurityDescriptor=NULL; //安全描述符号一般都设置成NULL,即默认描述符 sa.nLength=sizeof(SECURITY_ATTRIBUTES); //管道长度 if(!CreatePipe(&hRead,&hWrite,&sa,0)) { printf("创建匿名函数失败!\n"); } if(!CreatePipe(&hRead2,&hWrite2,&sa,0)) { printf("创建匿名函数失败!\n"); } STARTUPINFO sui; PROCESS_INFORMATION pi; //调用ZeroMemory方法将该结构体中的所有成员都置为0,这是因为这个结构体的成员很多,如果开始的时候没有置为0的话,那它的值是随机的,将这样的结构体传给CreateProcess,可能会影响到执行的结果。 memset(&sui,0,sizeof(STARTUPINFO)); sui.cb =sizeof(STARTUPINFO); //设置结构体的大小 sui.dwFlags |=STARTF_USESTDHANDLES; //该标识表示标准输入句柄,标准输出句柄和错误句柄是有用的 sui.hStdInput =hRead2; //将子进程的输入句柄设置成父进程的读句柄 sui.hStdOutput =hWrite; //将子进程的输出句柄设置成父进程的写句柄 sui.hStdError =GetStdHandle(STD_ERROR_HANDLE); //得到标准错误句柄,是父进程的错误句柄,该行代码在本程序中没有实际的用途意义 //因为是匿名管道,是没有名称的管道,只有通过CreateProcess由上而下的传递管道操作句柄。 //if(!CreateProcess(_T("c:\\windows\\system32\\cmd.exe"),NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi)) if(!CreateProcess(_T("D:\\Visual Studio 2012\\Projects\\boost测试\\Debug\\piple_child.exe"),NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi)) { printf("创建子进程失败!\n"); CloseHandle(hRead); CloseHandle(hWrite); CloseHandle(hRead2); CloseHandle(hWrite2); hRead=NULL; hWrite=NULL; hRead2=NULL; hWrite2=NULL; } else { //创建一个新的进程的时候,系统会创建一个进程内核对象和一个线程内核对象,内核对象都有一个使用基数,初始调用的时候,都设置为1。在CreateProcess返回之前,该函数打开进程和线程的内核对象,并将进程相关的句柄放置到结构体PROCESS_INFORMATION的hProcess和hThread中,当Process在内部打开这些对象的时候,使得每个对象的使用基数增加到2了。如果在父进程中不需要使用这两个句柄,就将这个句柄进行关闭,使得使用基数减1。当子进程终结的时候,系统会在将使用基数减1,使得子进程的进程内核对象和线程内核对象的使用基数变为0,这样内核对象就可以被释放了。 CloseHandle(pi.hProcess); //关闭子进程的句柄 CloseHandle(pi.hThread); //关闭子进程中主线程的句柄 } char *buf= "ping www.sina.com.cn\r\n"; DWORD dwWrite; //进程的输入重定向到hReadPipe2,所以从hWritePipe2写入 if(!WriteFile(hWrite2,buf,strlen(buf)+1,&dwWrite,NULL)) { printf("匿名管道写入数据失败!\n"); } char bufRead[1000]; DWORD dwRead; while (true) { //进程的输出重定向到hWritePipe1,所以从hReadPipe1读取 if(!ReadFile(hRead,bufRead,1000 -1 ,&dwRead,NULL)) { printf("匿名管道读取数据失败!\n"); } else { bufRead[dwRead] = '\0'; printf("%s\n",bufRead); } } }
View Code
#include "stdafx.h" #include <Windows.h> int _tmain(int argc, _TCHAR* argv[]) { DWORD dwReaded =0; HANDLE hRead = GetStdHandle(STD_INPUT_HANDLE); HANDLE hWrite = GetStdHandle(STD_OUTPUT_HANDLE); //HANDLE hRead2 = GetStdHandle(STD_INPUT_HANDLE); //HANDLE hWrite2 = GetStdHandle(STD_OUTPUT_HANDLE); if( hRead ) { /*'从管道接收数据*/ const int nBufSize = 2048; char szBuf[nBufSize]; if(ReadFile(hRead, &szBuf,nBufSize, &dwReaded, NULL)) { //char buf[]="http://www.sina.com.cn"; DWORD dwWrite; if(!WriteFile(hWrite,szBuf,dwReaded,&dwWrite,NULL)) { printf("写入数据失败!\n"); } } } //printf("child\n"); return 0; }