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

    技术2022-05-19  21

    其他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


    最新回复(0)