进程间通信(三):利用命名管道
进程间通信的四种方式
1) 剪贴板
2) 匿名管道
3) 命名管道
4) 邮槽
命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。
将命名管道作为一种网络编程方案时,它实际上建立了一个客户机/服务器通信体系,并在其中可靠地传输数据。
命名管道是围绕Windows文件系统设计的一种机制,采用“命名管道文件系统(Named Pipe File System,NPFS)”接口,因此,客户机和服务器可利用标准的Win32文件系统函数(例如:ReadFile和WriteFile)来进行数据的收发。
命名管道服务器和客户机的区别在于:服务器是唯一一个有权创建命名管道的进程,也只有它才能接受管道客户机的连接请求。而客户机只能同一个现成的命名管道服务器建立连接。
命名管道提供了两种基本通信模式:字节模式和消息模式。在字节模式中,数据以一个连续的字节流的形式,在客户机和服务器之间流动。而在消息模式中,客户机和服务器则通过一系列不连续的数据单位,进行数据的收发,每次在管道上发出了一条消息后,它必须作为一条完整的消息读入。
CreateNamedPipe用来创建命名管道,ConnectNamedPipe被服务器端用来等待客户端连接的到来,
创建命名管道以及判断是否有连接到来的代码如下:
m_hpipe=CreateNamedPipe(".//pipe//mypipe",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,0,1,1024,1024,0,NULL);
if(INVALID_HANDLE_VALUE==m_hpipe)
{
MessageBox("创建命名管道失败/n");
CloseHandle(m_hpipe);
m_hpipe=NULL;
return ;
}
HANDLE hevent=CreateEvent(NULL,TRUE,FALSE,NULL);//
if(!hevent)
{
MessageBox("创建事件对象失败/n");
CloseHandle(m_hpipe);
m_hpipe=NULL;
return ;
}
OVERLAPPED overlap;
ZeroMemory(&overlap,sizeof(OVERLAPPED));
overlap.hEvent=hevent;
//如果m_hpipe是以FILE_FLAG_OVERLAPPED打开的,则必须使用CreateEvent得到的句柄赋值给OVERLAPPED结构体中的hEvent
if(!ConnectNamedPipe(m_hpipe,&overlap))
{
if(ERROR_IO_PENDING!=GetLastError())//Overlapped I/O operation is in progress.
{
MessageBox("等待客户端连接失败/n");
CloseHandle(m_hpipe);
CloseHandle(hevent);
m_hpipe=NULL;
return ;
}
}
if(WAIT_FAILED==WaitForSingleObject(hevent,INFINITE))
{
MessageBox("等待对象失败/n");
CloseHandle(m_hpipe);
CloseHandle(hevent);
m_hpipe=NULL;
return ;
}
CloseHandle(hevent);
从命名管道读取数据代码如下:
char buf[100];
DWORD dwRead;
if(!ReadFile(m_hpipe,buf,100,&dwRead,NULL))
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
从命名管道写入数据代码如下:
char buf[]="welcome to my blog";
DWORD dwWrite;
if(!WriteFile(m_hpipe,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("写入数据失败!");
return;
}