匿名管道只能用来实现同一台机器上父子进程间通信,而不能实现跨网络的通信。
利用匿名管道实现父子进程通信时,需要注意:因为匿名管道没有名称,所以只能在父进程中调用Createprocess函数创建子线程时,将管道的读写句柄传递给子线程。
1.父进程代码
private:
HANDLE m_hRead;//匿名管道读句柄
HANDLE m_hWrite;//匿名管道写句柄
void CParentView::OnPipeCreate()
{
SECURITY_ATTRIBUTES sa;//定义安全结构体
sa.bInheritHandle = TRUE;//可以被子进程所继承
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
if (!CreatePipe(&m_hRead, &m_hWrite, &sa, 0))//创建管道
{
MessageBox("创建管道失败!");
return;
}
STARTUPINFO sui;
PROCESS_INFORMATION pi;
ZeroMemory(&sui, sizeof(STARTUPINFO));
sui.cb = sizeof(STARTUPINFO);
sui.dwFlags = STARTF_USESTDHANDLES;
sui.hStdInput = m_hRead;//设置子进程的标准输入句柄为管道读句柄
sui.hStdOutput = m_hWrite;//设置子进程的标准输出句柄为管道写句柄
sui.hStdError = GetStdHandle(STD_ERROR_HANDLE);//设置子进程的错误句柄为父进程错误句柄
if (!CreateProcess("..\\..\\Child\\Debug\\Child.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi))//创建子进程
{
CloseHandle(m_hRead);
CloseHandle(m_hWrite);
m_hRead = NULL;
m_hWrite = NULL;
MessageBox("创建子进程失败!");
return;
}
else
{
CloseHandle(pi.hProcess);//子进程内核对象计数减1
CloseHandle(pi.hThread);//子进程主线程内核对象计数减1
}
}
void CParentView::OnPipeRead()
{
char buf[100];
DWORD dwRead;
if (!ReadFile(m_hRead,buf,100,&dwRead,NULL))//利用匿名管道的读句柄从管道中读取数据
{
MessageBox("读取数据失败!");
return;
}
else
{
MessageBox(buf);
}
}
void CParentView::OnPipeWrite()
{
char buf[]="dadadadakai";
DWORD dwWrite;
if (!WriteFile(m_hWrite,buf,strlen(buf)+1, &dwWrite, NULL))//利用匿名管道的写句柄从管道中写入数据
{
MessageBox("写入数据失败!");
return;
}
}
2.子进程代码
private:
HANDLE m_hRead;//匿名管道读句柄
HANDLE m_hWrite;//匿名管道写句柄
void CChildView::OnInitialUpdate()
{
CView::OnInitialUpdate();
m_hRead = GetStdHandle(STD_INPUT_HANDLE);//获取标准输入句柄
m_hWrite = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出句柄
}
void CChildView::OnPipeRead()
{
char buf[100];
DWORD dwRead;
if (!ReadFile(m_hRead, buf, 100, &dwRead, NULL))//使用标准输入句柄(即匿名管道读句柄)读取数据
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
}
void CChildView::OnPipeWrite()
{
char buf[]="yyyyyyxue";
DWORD dwWrite;
if (!WriteFile(m_hWrite, buf, strlen(buf)+1, &dwWrite, NULL))//使用标准输出句柄(即匿名管道写句柄)写入数据
{
MessageBox("写入数据失败!");
return;
}
}