「命名管道」其他API函数及错误和性能问题

其他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:由WriteFileReadFile函数返回ERROR_INVALID_PARAMETER错误

假如在一个命名管道上工作,并使用重叠式I/O

那么WriteFileReadFile函数调用都有可能失败,并返回ERROR_INVALID_PARAMETER错误。

这种失败一项可能的促因是OVERLAPPED结构的Offset以及OffsetHigh这两个成员未设为0

 

Q180222Windows 95WaitNamedPipe253号错误

Windows 95中,假如将一个无效管道名作为第一个参数传递,

那么在WaitNamedPipe函数调用失败以后,用GetLastError会返回一个错误253

对这个函数来说, 253并非一个标准的(事先定义的)错误代码。

而假如换到Windows NT 4上运行同样的代码,

返回的错误代码是161ERROR_BAD_PTHNAME)。

要想解决这种不一致的问题,请将253号错误解释成标准的161号错误:ERROR_BAD_PTHNAME(路径名错误)。

 

Q141709:单台工作站最多只能建立49个命名管道连接

假如命名管道服务器应用创建了49个以上的直接命名管道,那么在远程计算机上,一个

客户机最多只能建立前面的49个命名管道连接,多余的只好忽略。

 

Q126645:从某项服务打开一个命名管道时,出现访问被拒的情况

假如一项服务采用“本地系统”帐号运行,同时试图打开在Windows NT上运行的一个命

名管道,那么操作便会失败,并返回“拒绝访问”错误信息,亦即错误代码5

你可能感兴趣的:(工作,windows,server,api,服务器,winapi)