命名管道通过网络来完成进程间通信,它屏蔽了底层的网络协议细节。
采用命名管道完成进程通信的过程为:
1.在服务器端调用CreateNamedPipe创建命名管道之后,调用ConnectNamedPipe函数让服务器进程等待客户端进程连接到该命名管道的实例上。
2.在客户端,首先调用WaitNamedPipe函数判断当前是否有可以利用的命名管道实例,如果有就调用CreateFile函数打开该命名管道的实例,并建立一个连接。
之后就可以通过ReadFile、WriteFile进行通信。
服务端
void CNamedPipeSrcView::OnPipeCreate()
{
//创建命名管道
m_hPipe = CreateNamedPipe("\\\\.\\pipe\\MyPipe",
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, 0, 1, 1024, 1024, 0, NULL);
if (INVALID_HANDLE_VALUE == m_hPipe)
{
MessageBox("创建命名管道失败!");
m_hPipe = NULL;
return;
}
//创建匿名的人工重置事件对象
HANDLE hEvent;
hEvent = CreateEvent(NULL, TRUE, FALSE,NULL);
if (!hEvent)
{
MessageBox("创建事件对象失败");
CloseHandle(m_hPipe);
m_hPipe = NULL;
return;
}
OVERLAPPED ovlap;
ZeroMemory(&ovlap, sizeof(OVERLAPPED));
ovlap.hEvent = hEvent;
//等待客户端请求的到来
if (!ConnectNamedPipe(m_hPipe, &ovlap))
{
if (ERROR_IO_PENDING != GetLastError())
{
MessageBox("等待客户端连接失败!");
CloseHandle(m_hPipe);
CloseHandle(hEvent);
m_hPipe = NULL;
return;
}
}
if (WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE))
{
MessageBox("等待事件对象失败!");
CloseHandle(m_hPipe);
CloseHandle(hEvent);
m_hPipe = NULL;
return;
}
CloseHandle(hEvent);//执行到这一步,说明已经有客户端连上命名管道实例,不再需要该事件对象句柄
}
void CNamedPipeSrcView::OnPipeRead()
{
char buf[100];
DWORD dwRead;
if (!ReadFile(m_hPipe, buf, 100, &dwRead, NULL))
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
}
void CNamedPipeSrcView::OnPipeWrite()
{
char buf[]="dadadadakai";
DWORD dwWrite;
if (!WriteFile(m_hPipe, buf, strlen(buf)+1, &dwWrite, NULL))
{
MessageBox("写入数据失败!");
return;
}
}
客户端
void CNamedPipeClientView::OnPipeConnect()
{
//判断是否有可以利用的命名管道
if (!WaitNamedPipe("\\\\.\\pipe\\MyPipe", //如果是跨网络通信,则在圆点处指定服务器端程序所在的主机名
NMPWAIT_USE_DEFAULT_WAIT))
{
MessageBox("当前没有可以利用的命名管道实例!");
return;
}
//打开可用的命名管道,并与服务器端进程进行通信
m_hPipe = CreateFile("\\\\.\\pipe\\MyPipe",
GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == m_hPipe)
{
MessageBox("打开命名管道失败!");
m_hPipe = NULL;
return;
}
}
void CNamedPipeClientView::OnPipeRead()
{
char buf[100];
DWORD dwRead;
if (!ReadFile(m_hPipe,buf,100,&dwRead,NULL))//利用命名管道读取数据
{
MessageBox("读取数据失败!");
return;
}
else
{
MessageBox(buf);
}
}
void CNamedPipeClientView::OnPipeWrite()
{
char buf[]="yyyyyyyxue";
DWORD dwWrite;
if (!WriteFile(m_hPipe,buf,strlen(buf)+1, &dwWrite, NULL))//利用命名管道写入数据
{
MessageBox("写入数据失败!");
return;
}
}
本文链接:https://www.it72.com:4443/12331.htm