命名管道也是进程通信的一种方式,比匿名方式强大了不少,主要有了网络的支持.闲话休提,
HANDLE CreateNamedPipe(
LPCTSTR lpName, // 管道名
DWORD dwOpenMode, // 管道的打开方式
DWORD dwPipeMode, // 管道传输类型
DWORD nMaxInstances, // 最大的实例数
DWORD nOutBufferSize, // 输出缓冲大小
DWORD nInBufferSize, // 输入缓冲大小
DWORD nDefaultTimeOut, // 超时时间
LPSECURITY_ATTRIBUTES lpSecurityAttributes // 安全描述
);
实例代码:
hPipe=CreateNamedPipe(".//pipe//MyPipe",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
0,1,1024,1024,0,NULL);
if(INVALID_HANDLE_VALUE==hPipe)
{
MessageBox("创建命名管道失败!");
hPipe=NULL;
return;
}
注意:管道名的格式,管道的打开方式,因为由于使用了FILE_FLAG_OVERLAPPED,后面将使用人工事件;
实例代码:
HANDLE hEvent;
hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!hEvent)
{
MessageBox("创建事件对象失败!");
CloseHandle(hPipe);
hPipe=NULL;
return;
}
OVERLAPPED ovlap;
ZeroMemory(&ovlap,sizeof(OVERLAPPED));
ovlap.hEvent=hEvent;
注意:
BOOL ConnectNamedPipe(
HANDLE hNamedPipe, // handle to named pipe
LPOVERLAPPED lpOverlapped // overlapped structure
);
关于OVERLAPPED这个结构MSDN有一句话
If hNamedPipe was created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL,
the OVERLAPPED structure must contain a handle to a manual-reset event object
(which the server can create by using the CreateEvent function).
大致意思就是使用了FILE_FLAG_OVERLAPPED标志,并且lpOverlapped不为空那么将使用CreateEvent创建一个事件.
管道建立完毕后,将等待客户端连接了:
实例代码:
if(!ConnectNamedPipe(hPipe,&ovlap))
{
//还要判断一下是不是不正常的连接
if(ERROR_IO_PENDING!=GetLastError())
{
MessageBox("等待客户端连接失败!");
CloseHandle(hPipe);
CloseHandle(hEvent);
hPipe=NULL;
return;
}
}
//超时
if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))
{
MessageBox("等待对象失败!");
CloseHandle(hPipe);
CloseHandle(hEvent);
hPipe=NULL;
return;
}
CloseHandle(hEvent);
之后可以编写服务端/客户端的读写操作:
实例代码:
读:
char buf[100];
DWORD dwRead;
if(!ReadFile(hPipe,buf,100,&dwRead,NULL))
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
写:
char buf[]="这是一个写的例子";
DWORD dwWrite;
if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("写入数据失败!");
return;
}
当然,客户端首先得连接服务端管道要不然,我们之前写的代码一点价值都没有:
实例代码:
if(!WaitNamedPipe(".//pipe//MyPipe",NMPWAIT_WAIT_FOREVER))
{
MessageBox("当前没有可利用的命名管道实例!");
return;
}
hPipe=CreateFile(".//pipe//MyPipe",GENERIC_READ | GENERIC_WRITE,
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==hPipe)
{
MessageBox("打开命名管道失败!");
hPipe=NULL;
return;
}
代码很简单,就不解释了.