实验四:使用命名管道实现进程通信
一、实验目的
- 了解windows系统环境下的进程通讯机制。
- 熟悉Windows系统提供的进程通信API。
二、实验准备
相关API函数介绍
建立命名管道
函数CreateNamePipe()创建一个命名管道实例,并返回该管道的句柄。
原型:
HANDLE CreateNamePipe(
LPCTSTR lpName, //命名管道的名字
DWORD dwOpenMode, //命名管道的访问模式
DWORD dwPipe’Mode, //命名管道的模式
DWORD nMaxInstances, //可创建实例的最大值
DWORD nOutBufferSize, //以字节为单位的输出缓冲区的大小
DWORD nInBufferSize, //以字节为单位的输入缓冲区的大小
DWORD nDefaultTimeOut, //默认超时时间
LPSECURITY_ATTRIBUTES lpSecurityAttributes //安全属性
);
参数说明:
- lpName:为命名管道的名字,管道的命名方式为\\ServerName\pipe\pipename,其中ServerName为用命名管道通信时服务器的主机名或IP地址,pipename为命名管道的名字,用户可自行定义。
- dwOpenMode:指出命名管道的访问模式。模式如表2-5所示。
- dwPipeMode:指出管道的模式。模式如表2-6所示、
- nMaxInstances:该命名管道可以创建实例的最大值。
- nOutBufferSize:输出缓冲区的大小,以字节为单位。
- nInBufferSize:输入缓冲区的大小,以字节为单位。
- nDefaultTimeOut:默认的超时时间,以ms为单位。如果函数WaitNamePipe()指出- NMWAIT_USE_DEFAULT_WAIT,每个管道实例必须指定同一值的名字。
- lpSecurityAttributes:为管道指定安全属性,为NULL时,管道得到一个默认的安全描述符。
返回值:
如果管道创建成功,将返回服务器命名管道实例的句柄。如果失败,返回INVALID_HANDLE_VALUE,可以调用函数GetLastError()查询失败的原因;当返回ERROR_INVALID_PARAMETER时,表明参数nMaxInstances指定的值大于PIPE_UNLIMTED_INSTANCES。
连接命名管道
服务器用函数ConnectNamePipe()连接命名管道。创建后命名管道也等待客户端的连接,客户端可以使用函数CreateFile()和CallNamedPipe()进行连接。
原型:
BOOL ConnectNamedPipe(
HANDLE hNamePipe, //命名管道实例句柄
LPOVERLAPPED lpOver lapped //指向Overlapped结构的指针
);
参数说明:
hNamedPipe:为命名管道创建时得到的一个命名管道实例句柄。
lpOverlapped:指向Overlapped结构的指针,可设其为NULL。
返回值:
成功,将返回一个非0值;失败,系统返回0,可以调用函数GetLastError()查询失败的原因。
拆除命名管道的连接
函数DisconnectNamePipe()拆除命名管道服务器与客户端的连接。
原型:
BOOL DisconnectNamePipe(
HANDLE hNamePipe
);
参数说明:
hNamedPipe:为命名管道创建时得到的一个命名管道实例句柄。
返回值:
成功,将返回一个非0值;失败,系统返回0,可以调用函数GerLasrError()查询失败的原因。
客户端连接服务器已建立的命名管道
客户端使用函数CallNamePipe()连接服务器建立的命名管道。
原型:
BOOL CallNamePipe(
LPCTSTR lpNamePipeName, //命名管道的名字
LPVOID lpInBuffer, //输出数据缓冲区
DWORD nInBufferSize, //以字节为单位的输出数据缓冲区的大小
LPVOID lpOurBuffer, //输入数据缓冲区指针
DWORD nOurBufferSize, //以字节为单位的输入数据缓冲区的大小
LPDWORD lpBytesRead, //输入字节数指针
DWORD nTimeOUT //等待时间
);
参数说明:
lpNamedPipeName:命名管道的名字。
lpInBuffer:指出用于输出数据(向管道写数据)的缓冲区指针。
nInBufferSize:用于输出数据缓冲区的大小,以字节为单位。
lpOutBuffer:指出用于接收数据(从管道读出数据)的缓冲区指针。
nOutBufferSize:指向用于接收数据缓冲区的大小,以字节为单位。
lpBytesRead:一个32位的变量,改变量用于存储从管道读出的字节数。
nTimeOut:等待命名管道成为可用状态的时间,单位为ms。
返回值:
成功,将返回一个非0值;失败,系统返回0,可用调用函数GetLastError()查询失败的原因。
客户端等待命名管道
客户端使用函数WaitNamedPipe()等待服务器连接命名管道。
原型:
BOOL WaitNamedPipe(
LPCTSTR lpNamedPipeName, //要等待的命名管道名
DWORD nTimeOut //等待时间
);
参数说明:
lpNamedPipeName:要等待的命名管道的名字。
nTimeOut:等待命名管道成为可用状态的时间,单位为ms.
返回值:
在等待时间内要连接的命名管道可以使用,将返回一个非0值。在等待时间内要连接的命名管道不可以使用,系统返回0,可用调用GetLastError()查询失败的原因。
三、实验内容
(一)实验内容
- 使用Windows系统提供的命名管道完成两个进程之间的通信,能正确使用创建命名管道CreateNamePipe(),连接命名管道ConnectNamePipe(),拆除命名道的连接DisconnectNamePipe(),连接服务器已建立的命名管道CallNamePipe(),等待命名管道WaitNamedPipe()等API.
- 在客户端输入信息传入服务器,再从服务器输入信息传入客户端。
(二)主要代码
服务器的代码
// PipeServe.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "PipeServe.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[