作者: 徐原
能实现局域网上两台主机间文件拷贝的方法有很多种,这里介绍的“命名管道”(Named Pipe )是一种比较可靠的进程间通信机制,可用在同一台计算机不同进程间,也可用在不同
计算机的不同进程间,可以是单向的,也可以是双向的,Windows NT、Windows 2000、Windows 95和Windows 98均提供了对它的支持,而且在Unix下也有类似的概念。它是在Microsoft LAN管理器和IBMLAN服务器网络操作系统上实现的。
命名管道使用了MSNP(微软网络提供者)重定向器,这样应用
程序便可以不用了解网络协议的细节而利用该机制实现网络上的数据传输。它采用“命名管道文件系统”(Named Pipe File System)接口,其命名是采用UNC(通用命名规范)格式的:
\\ServerName\Pipe\[pipename]
\\ServerName指明命名管道是在那个服务器上创建的,ServerName既可以是一个实际的
计算机名,也可以是小数点(“.”)以指明是在本机上创建;\Pipe是一个硬编码(Hardcode)不用区分大小写的字符串用以指明这是一个管道名,该文件名从属于NPFS;[pipename]是实际的自定义的管道名,该名称在前面指定的服务器上必须是唯一的,该名称可以包含多级目录,但目录名必须不是已经创建的管道名,例:
\\.\Pipe\xyPipe’这是一个合法管道名
\\.\Pipe\xyPipe\Pipe’这不是一个合法的管道名,因为前面的目录\\.\Pipe\xyPipe是一个已经创建的管道名了。
\\.\Pipe\xxyPipe\Pipe’这也是一个合法的文件名
命名管道有两种基本通信模式:字节模式和消息模式。在字节模式中,数据是以字节流的形式在管道种传输,数据之间没有边界,在管道写入和读出操作中是以字节流即数据块为基本单位操作的,这适合传输大容量数据;在消息模式中,数据是以一条条不连续的消息为基本传输单元,消息和消息之间有边界,在管道写入和读出操作中也是以消息为单位进行操作的,这种方式适合传输量小的数据。因为现在的文件大小常常有几百K甚至更大,所以
程序中选择使用字节模式。
下面详细介绍一下CreateNamedPipe()这个函数,该函数C原型如下:
HANDLE CreateNamedPipe(
LPCTSTR lpName, // pointer to pipe name
DWORD dwOpenMode, // pipe open mode
DWORD dwPipeMode, // pipe-specific modes
DWORD nMaxInstances, // maximum number of instances
DWORD nOutBufferSize, // output buffer size, in bytes
DWORD nInBufferSize, // input buffer size, in bytes
DWORD nDefaultTimeOut, // time-out time, in milliseconds
LPSECURITY_ATTRIBUTES lpSecurityAttributes // pointer to security attributes
);
lpName:为前面所述的命名管道名。
dwOpenMode:为命名管道打开的模式,有PIPE_ACCESS_DUMPLEX(双向)、PIPE_ACCESS_INBOUND(输入)、PIPE_ACCESS_OUTBOUND(输出)这三种,这些标志还可以和一些附加的I/O控制和安全模式的常数组合使用,详细可参考MSDN。
dwPipeMode:为管道传输模式,有前面所述的PIPE_TYPE_BYTE(字节模式)和PIPE_TYPE_MESSAGE(消息模式)两种,可以和PIPE_READMODE_BYTE和PIPE_READMODE_MESSAGE常数组合使用以限定客户端的读取模式。可以使用PIPE_TYPE_MESSAGE 和 PIPE_READMODE_BYTE组合来指定发送者以消息模式向管道发送数据,而接收者一次可以读取任意数量的字节。注意不可将PIPE_TYPE_BYTE和PIPE_READMODE_MESSAGE组合使用,这样会导致CreateNamedPipe()函数调用失败,因为字节模式没有边界,在接收端用消息模式读取的时候无法判断消息的边界。
nMaxInstances:管道最大的连接实例句柄,其范围在1到255之间。
nOutBufferSize和nInBufferSize分别指明管道输出和输入缓冲区的大小,如设为0则使用系统默认大小。
nDefau