注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mihooke's blog

IT之恋

 
 
 

日志

 
 

匿名管道(Windows)  

2016-12-02 18:37:44|  分类: C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 BOOL CreatePipe(PHANDLE hReadPipe, // 指向读句柄的指针
 PHANDLE hWritePipe, // 指向写句柄的指针
 LPSECURITY_ATTRIBUTES lpPipeAttributes, // 指向安全属性的指针
 DWORD nSize // 管道大小);
管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。匿名管道(Anonymous Pipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。
管道服务器将lpPipeAttributes 指向的SECURITY_ATTRIBUTES数据结构数据成员bInheritHandle设置为TRUE,那么CreatePipe()创建的管道读、写句柄将会被继承。lpPipeAttributes一般可以这么用:
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
cout<<"create pipe fail!"<<endl;
}
父进程可以调用进程创建函数CreateProcess()生成子进程。如果父进程要发送数据到子进程,父进程可调用WriteFile()将数据写入到管道(传递管道写句柄给函数),子进程则调用GetStdHandle()取得管道的读句柄,将该句柄传入ReadFile()后从管道读取数据。
  如果是父进程从子进程读取数据,那么由子进程调用GetStdHandle()取得管道的写入句柄,并调用WriteFile()将数据写入到管道。然后,父进程调用ReadFile()从管道读取出数据(传递管道读句柄给函数)。
在用WriteFile()函数向管道写入数据时,只有在向管道写完指定字节的数据后或是在有错误发生时函数才会返回。如管道缓冲已满而数据还没有写完,WriteFile()将要等到另一进程对管道中数据读取以释放出更多可用空间后才能够返回。管道服务器在调用CreatePipe()创建管道时以参数nSize对管道的缓冲大小作了设定。

附上两个例子:第一个是主进程(main)中创建管道,写入管道数据,再读取管道中的数据并输出;第二个是主进程(main)创建子进程,在子进程中读取数据,并把数据返回到管道中,再由主程序(main)输出。
第一个实例:
#include <iostream>
#include <Windows.h>
using namespace std;

int main()
{
HANDLE hRead;
HANDLE hWrite;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;

/*创建匿名管道*/
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
cout<<"create pipe fail!"<<endl;
return 1;
}

DWORD dwWritten = 0;
char cBuf[10] = "string";
/*string写入pipe中*/
WriteFile(hWrite, cBuf, 10, &dwWritten, NULL);
CloseHandle(hWrite);

char cBuf2[10] = {0};
DWORD len = 0;
/*从pipe中读取string并放到cBuf2中*/
ReadFile(hRead, cBuf2, 10, &len, NULL);
CloseHandle(hRead);
cout<<cBuf2<<endl;
system("pause");
return 0;
}//end~
第二个实例

server.cpp---主进程main
#include <iostream>
#include <Windows.h>
using namespace std;

int main()
{
HANDLE hRead, hWrite;
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
/*创建匿名管道*/
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
cout<<"create pipe fail!"<<endl;
return 1;
}
STARTUPINFO sui;
PROCESS_INFORMATION pi;
ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb = sizeof(STARTUPINFO);
sui.dwFlags = STARTF_USESTDHANDLES;
sui.hStdInput = hRead;
sui.hStdOutput = hWrite;
sui.wShowWindow = SW_SHOW;
sui.hStdError = GetStdHandle(STD_ERROR_HANDLE);
/*创建子进程 --- 在该工程下添加另一个工程client*/
if (!CreateProcess("..\\Debug\\client.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi))
{
cout<<"create chlid process fail!"<<endl;
CloseHandle(hRead);
CloseHandle(hWrite);
return 2;
}
char cBuf[100] = "this is a string";
DWORD wWrite;
/*写入pipe数据---该数据会由客户端client.exe输出*/
WriteFile(hWrite, cBuf, 18, &wWrite, NULL);
CloseHandle(hWrite);

system("pause");
return 0;
}

client.cpp---子进程
#include <iostream>
#include <Windows.h>
using namespace std;

int main()
{
HANDLE hRead, hWrite;
hRead = GetStdHandle(STD_INPUT_HANDLE);
hWrite = GetStdHandle(STD_OUTPUT_HANDLE);
char cBuf[100] = {0};
DWORD wRead = 0;
ReadFile(hRead, cBuf, 100, &wRead, NULL);
CloseHandle(hRead);
cout<<cBuf<<endl;
return 0;
}

  评论这张
 
阅读(26)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017