9、进程通信之命名管道

命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。

命名管道充分利用了Windows NTWindows 2000内建的安全机制。

将命名管道作为一种网络编程方案时,它实际上建立了一个客户机/服务器通信体系,并在其中可靠地传输数据。

命名管道是围绕Windows文件系统设计的一种机制,采用命名管道文件系统(Named Pipe File SystemNPFS)”接口,因此,客户机和服务器可利用标准的Win32文件系统函数(例如:ReadFileWriteFile)来进行数据的收发。

命名管道服务器和客户机的区别在于:服务器是唯一一个有权创建命名管道的进程,也只有它才能接受管道客户机的连接请求。而客户机只能同一个现成的命名管道服务器建立连接。

命名管道服务器只能在Windows NTWindows 2000上创建。

命名管道提供了两种基本通信模式:字节模式和消息模式。在字节模式中,数据以一个连续的字节流的形式,在客户机和服务器之间流动。而在消息模式中,客户机和服务器则通过一系列不连续的数据单位,进行数据的收发,每次在管道上发出了一条消息后,它必须作为一条完整的消息读入。

HANDLE CreateNamedPipe()

CreateNamedPipe,创建命名管道,其中第一个参数管道的名称是格式为"\\.\pipe\pipename", VC中使用的时候,因涉及到转义符,作为字符串,应使用"\\\\.\\pipe\\pipename",其中pipe不能更改,大小写没有区分

hPipe=CreateNamedPipe("\\\\.\\pipe\\MyPipe",PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,0,1,1024,1024,0,NULL);

if(INVALID_HANDLE_VALUE==hPipe)

{

MessageBox("创建命名管道失败!");

CloseHandle(hPipe);

hPipe=NULL;

return;

}

HANDLE hEvent;

hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if(!hEvent) 

{

MessageBox("创建事件对象失败!");

CloseHandle(hPipe);

hPipe=NULL;

return;

}

OVERLAPPED ovlap;

//这里调用ZeroMemory和上一章的意义是一样的,为了避免ConnectNamedPipe在调用该结构中使用的是一些不可欲知的参数值,防止有影响

ZeroMemory(&ovlap,sizeof(OVERLAPPED));

ovlap.hEvent=hEvent;

说明:等待客户端连接到一个命名管道实例。If hNamedPipe was created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the OVERLAPPED structure

pointed to by lpOverlapped must contain a handle to a manual-reset event object (which the server can create by using the CreateEvent function).

这是为什么上面需要申明一个自动的事件的对象。

The ConnectNamedPipe function enables a named pipe server process to wait for

a client process to connect to an instance of a named pipe.

if(!ConnectNamedPipe(hPipe,&ovlap))

{

if(ERROR_IO_PENDING!=GetLastError())

{

MessageBox("等待客户端的连接失败!");

CloseHandle(hPipe);

CloseHandle(hEvent);

hPipe=NULL;

}

}

//等待事件状态有效,如果当前无效,INFINITE参数表明则一直等待下去

if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))

{

MessageBox("等待对象失败!");

CloseHandle(hPipe);

CloseHandle(hEvent);

hPipe=NULL;

}

CloseHandle(hEvent); //说明已经有客户端连接到了

命名管道的读写和上一章是类似的,这里就省略掉了

命名管道的客户端实现(核心为命名管道的连接):

//WaitNamePipe的参数NMPWAIT_WAIT_FOREVER一直等待下去,直到等待到可用的连接,当然也可以设置超时的时间,但前提是所有的程序里所有的命名管道的超时时间必须一样

if(!WaitNamedPipe("\\\\.\\pipe\\MyPipe",NMPWAIT_WAIT_FOREVER))

{

MessageBox("当前没有可用的命名管道实例");

return;

}

//打开命名管道,建立连接

hPipe=CreateFile("\\\\127.0.0.1\\pipe\\MyPipe",GENERIC_READ|GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INVALID_HANDLE_VALUE==hPipe)

{

MessageBox("打开命名管道失败!");

hPipe=NULL;

}

注意:程序的运行方式为先点击服务端的创建命名管道,然后点击客户端的连接管道,再点击服务端的发送数据,再在客户端点击接收数据。

参考

1MSDN

2]《VC++ 深入》

3http://blog.csdn.net/liufei_learning/archive/2009/12/17/5026410.aspx

 

posted @ 2010-09-18 22:27  浪里飞  阅读(1664)  评论(0编辑  收藏  举报