Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何获取要在命名管道中读取(可靠)的数据长度?_C++_Windows_Winapi_Named Pipes - Fatal编程技术网

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

C++ 如何获取要在命名管道中读取(可靠)的数据长度?,c++,windows,winapi,named-pipes,C++,Windows,Winapi,Named Pipes,我已创建具有以下标志的命名管道: 管道\u访问\u双工-两侧读/写访问 管道类型消息-消息类型已读 管道等待-阻止读\写 我从服务器端打电话,等待客户端连接 从客户端,我调用连接到服务器并写入长度为N的数据 在服务器端: 在客户端连接之后,调用以获取要分配的缓冲区长度,以读取数据缓冲区 在得到确切的缓冲区大小(N)后,我将分配长度为N的缓冲区,并调用从管道读取数据 问题: 问题在于——在单处理器机器上,PeekNamedPipe API将缓冲区长度返回为0。由于此原因,以后读取文件失败

我已创建具有以下标志的命名管道:

  • 管道\u访问\u双工-两侧读/写访问
  • 管道类型消息-消息类型已读
  • 管道等待-阻止读\写
我从服务器端打电话,等待客户端连接

从客户端,我调用连接到服务器并写入长度为N的数据

在服务器端:

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

  • 问题在于——在单处理器机器上,PeekNamedPipe API将缓冲区长度返回为0。由于此原因,以后读取文件失败
  • 经过一些调查,我发现由于某些竞争条件,甚至在客户端将数据放入管道之前,就调用了PeekNamedPipe API
  • 你知道如何解决这个竞赛条件吗?我需要调用PeekNamedPipe来获取缓冲区大小,并且在数据可用之前不能调用PeekNamedPipe
我曾想过引入自定义头来指示消息本身的缓冲区长度,但这听起来有很多变化


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

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

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

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

  • 如果客户端在CreateNamedPipe()调用之后立即进行连接,则服务器端的ConnectNamedPipe()可能返回错误\u PIPE\u CONNECTED。只需将其视为连接
  • 客户端的WaitNamedPipe在超时时不会设置错误。假设超时
  • 如果另一个客户端成功调用WaitNamedPipe()后仍设法首先获取管道,则客户端上的CreateFile()可能返回错误\u PIPE\u BUSY。返回WaitNamedPipe状态
  • 如果客户端已经看到消息并关闭了管道,FlushFileBuffers()可能会返回错误\u PIPE\u NOT \u CONNECTED。别理它
  • 重叠的ReadFile()调用可能会立即完成,并且不会返回错误\u IO\u PENDING。考虑读取完成。
  • 如果服务器尚未写入管道,则PeekNamedPipe()可能返回0。睡眠(1)并重复