其他API调用
CallNamedPipe函数允许客户机应用建立与一个消息类型的管道的连接
(假如当时没有可用的管道实例,便会一直等候下去)
然后在管道上读写数据,最后关闭这个管道。
函数原型
BOOL WINAPI CallNamedPipe(
__in LPCTSTR lpNamedPipeName, // 管道服务端名称
__in LPVOID lpInBuffer, // 数据发送缓冲区
__in DWORD nInBufferSize, // 发送缓冲区大小
__out LPVOID lpOutBuffer, // 数据接收缓冲区
__in DWORD nOutBufferSize, // 接收缓冲区大小
__out LPDWORD lpBytesRead, // 记录接收到的数据大小(字节)
__in DWORD nTimeOut // 等待管道可用的超时时间
);
TransactNamedPipe函数既可在客户机应用中使用,亦可在服务器应用中使用。
设计它的目的是为了将读操作与写操作整合到一个API调用之中。
这样减轻了MSNP重定向器收发数据的负担,所以能在一定程度上优化网络I/O的性能。
函数原型
BOOL WINAPI TransactNamedPipe(
__in HANDLE hNamedPipe, //要操作的管道句柄
__in LPVOID lpInBuffer, // 数据发送缓冲区
__in DWORD nInBufferSize, // 发送缓冲区大小
__out LPVOID lpOutBuffer, // 数据接收缓冲区
__in DWORD nOutBufferSize, // 接收缓冲区大小
__out LPDWORD lpBytesRead, // 记录接收到的数据大小(字节)
__inout_opt LPOVERLAPPED lpOverlapped
// 一个异步结构指针,用于使用重叠式I/O,以异步形式工作
);
GetNamedPipeHandleState函数用于索检与一个指定命名管道对应的信息。
比如运行模式(消息或字节模式)、管道实例数以及缓冲区信息等等。
在命令管道的一个实例的“存在时间”内,不同时间返回的信息也可能会发生变化。
函数原型
BOOL WINAPI GetNamedPipeHandleState(
__in HANDLE hNamedPipe, //要索检的管道句柄
// 返回当前管道的运行模式,返回值是一个旗标组合,可以用以下旗标进行&运算
// PIPE_NOWAIT 管道的句柄处于非阻塞模式。如果未指定此标志,则该管的句柄是在阻止模式下
// PIPE_READMODE_MESSAGE 管道是消息读取模式。若未指定此标志,则管道为字节只读模式
__out_opt LPDWORD lpState,
__out_opt LPDWORD lpCurInstances, // 当前的管道实例数量
// 实际发送给服务器之前,打算在客户机上收集的最大字节数
__out_opt LPDWORD lpMaxCollectionCount,
__out_opt LPDWORD lpCollectDataTimeout, // 接收等待的最长时间,以毫秒为单位
__out_opt LPTSTR lpUserName, // 一个缓冲区,索检客户端应用的用户名称
__in DWORD nMaxUserNameSize // 名称缓冲区大小
);
SetNamedPipeHandleState函数,我们可更改由GetNamedPipeHandleState函数了解到的管道特征。
函数原型
BOOL WINAPI SetNamedPipeHandleState(
__in HANDLE hNamedPipe, // 要更改的管道句柄
__in_opt LPDWORD lpMode, // 更改管道的运行模式
__in_opt LPDWORD lpMaxCollectionCount, // 更改管道的收集的最大字节数
__in_opt LPDWORD lpCollectDataTimeout // 更改管道的等待时间
);
GetNamedPipeInfo这个函数用于获得缓冲区大小以及管道实例最大数量信息。
函数原型
BOOL WINAPI GetNamedPipeInfo(
__in HANDLE hNamedPipe, // 要索检的管道句柄
__out_opt LPDWORD lpFlags, // 索检命名管道的类型,注1
__out_opt LPDWORD lpOutBufferSize, // 索检发送数据的内部缓冲区大小
__out_opt LPDWORD lpInBufferSize, // 索检接受数据的内部缓冲区大小
__out_opt LPDWORD lpMaxInstances // 索检可以创建的管道实例最大数量
);
注1、 lpFlags 参数可以是以下一个或多个值
PIPE_CLIENT_END :句柄是指向一个命名管道实例的客户端。这也是默认值。
PIPE_SERVER_END :句柄是指向一个命名管道实例的服务器端。
PIPE_TYPE_BYTE :命名管道是一个字节流模式的管道。这也是默认值。
PIPE_TYPE_MESSAGE :命名管道是一个消息模式的管道。
PeekNamedPipe函数可用它对命令管道内的数据进行浏览,
同时不需将其从管道的内部缓冲区中挪出
函数原型
BOOL WINAPI PeekNamedPipe(
__in HANDLE hNamedPipe, // 要窥探的管道句柄
__out_opt LPVOID lpBuffer, // 接受数据的缓冲区
__in DWORD nBufferSize, // 接受缓冲区的大小
__out_opt LPDWORD lpBytesRead, // 实际接受的数据大小
__out_opt LPDWORD lpTotalBytesAvail, // 可从管道发送的数据大小
// 消息内尚存的字节数量(前提是管道用消息模式打开)
// 假如一条消息的实际长度大于由lpBuffer参数指定缓冲区的长度;
// 消息内剩下的字节便会返回
// 在字节模式下,该参数则无论如何都会返回0
__out_opt LPDWORD lpBytesLeftThisMessage
);
平台和性能问题
Q100291:命名管道名字的限制
假如创建了名为//./Pipe/Mypipes的管道,
以后便不能创建名为//.Pipe/Mypipes/Pipe1的管道,
因为//./Pipe/Mypipes已经是一个管道名,不可作为子目录使用。
Q119218:命名管道写操作限制在64K之内
若API函数WriteFile试图用一个大于64KB的缓冲区,
向一个处于消息模式的命名管道写入数据,
该函数便会返回FALSE,而GetLastError调用会返回ERROR_MORE_DATA。
Q110148:由WriteFile或ReadFile函数返回ERROR_INVALID_PARAMETER错误
假如在一个命名管道上工作,并使用重叠式I/O,
那么WriteFile或ReadFile函数调用都有可能失败,并返回ERROR_INVALID_PARAMETER错误。
这种失败一项可能的促因是OVERLAPPED结构的Offset以及OffsetHigh这两个成员未设为0。
Q180222:Windows 95的WaitNamedPipe和253号错误
在Windows 95中,假如将一个无效管道名作为第一个参数传递,
那么在WaitNamedPipe函数调用失败以后,用GetLastError会返回一个错误253。
对这个函数来说, 253并非一个标准的(事先定义的)错误代码。
而假如换到Windows NT 4上运行同样的代码,
返回的错误代码是161(ERROR_BAD_PTHNAME)。
要想解决这种不一致的问题,请将253号错误解释成标准的161号错误:ERROR_BAD_PTHNAME(路径名错误)。
Q141709:单台工作站最多只能建立49个命名管道连接
假如命名管道服务器应用创建了49个以上的直接命名管道,那么在远程计算机上,一个
客户机最多只能建立前面的49个命名管道连接,多余的只好忽略。
Q126645:从某项服务打开一个命名管道时,出现访问被拒的情况
假如一项服务采用“本地系统”帐号运行,同时试图打开在Windows NT上运行的一个命
名管道,那么操作便会失败,并返回“拒绝访问”错误信息,亦即错误代码5。