代码之家  ›  专栏  ›  技术社区  ›  aJ.

如何获取要在命名管道中读取(可靠)的数据长度?

  •  2
  • aJ.  · 技术社区  · 15 年前

    • 管道\u访问\u双工-两侧读/写访问
    • 管道等待-阻止读\写

    ConnectNamedPipe 等待客户端连接。

    我从客户端打电话 CallNamedPipe 连接到服务器并写入长度为N的数据。

    在服务器端:

    • 客户端连接后, PeekNamedPipe 调用以获取要分配以读取数据缓冲区的缓冲区长度。
    • 在得到确切的缓冲区大小(N)后,我将分配长度为N的缓冲区并调用 ReadFile 从管道中读取数据。

    问题:

    • 经过一些调查,我发现由于某些竞争条件,甚至在客户端将数据放入管道之前,就调用了PeekNamedPipe API。

    我曾想过引入自定义头来指示消息本身的缓冲区长度,但这听起来有很多变化。

    有没有更好更可靠的方法来获取要从管道中读取的数据长度?

    3 回复  |  直到 15 年前
        1
  •  6
  •   Hans Passant    15 年前

    使用命名管道可以获得大量竞争条件。您必须在代码中处理它们。可能性:

    • 客户端的WaitNamedPipe在超时时不会设置错误。假设超时。
    • 如果客户端已经看到消息并关闭了管道,FlushFileBuffers()可能会返回错误\u PIPE\u NOT \u CONNECTED。别理它。
    • 重叠的ReadFile()调用可能会立即完成,并且不会返回错误\u IO\u PENDING。考虑读取完成。
        2
  •  1
  •   MSalters    15 年前

    听起来您需要一个非同步I/O。只要让Windows在数据可用时通知您,并在那一刻查看即可。

        3
  •  0
  •   ygrek    15 年前

    在任何情况下,在报头中有一个数据包大小都是一个好主意,这样可以减少协议对传输层的依赖。 或者,如果客户端发送数据并关闭管道,则可以使用ReadFile将数据累积到缓冲区中,直到EOF。