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