我有一个真实的的旧代码,来自一个在消息模式下使用命名管道的服务(PIPE_TYPE_MESSAGE
),该服务具有重叠的i/o(FILE_FLAG_OVERLAPPED
)。
该代码执行以下操作:
ReadFile
为4字节,具有重叠的i/o(标题+消息长度)。客户端编写此命令时调用了一次WriteFile
。
1.读取4个字节后,进行ReadFile
调用以读取消息的其余部分(具有已知长度)*,而无需指定OVERLAPPED
结构。
1.在执行命令之后,例程在阶段1继续并等待下一命令。
当我阅读文档时
重叠操作需要使用FILE_FLAG_OVERLAPPED标志创建的文件、命名管道或通信设备。当线程调用函数(如ReadFile函数)执行重叠操作时, 调用线程必须指定 * 指向OVERLAPPED结构的指针。(如果此指针为NULL,函数返回值可能会错误地指示操作已完成。)
我不得不假设这个代码将无法工作或至少被称为不正确...
事实上,这段代码已经有15年的历史了,在数百台机器上运行,没有任何问题。
那么,我是否必须告诉我的老板和同事,这段代码有缺陷,它能工作只是运气,这段代码需要更正?
1条答案
按热度按时间hgc7kmma1#
在阅读了更多的文档之后,我不得不得出结论,是的,代码可以说是不正确的,特别是
ReadFile
上的这些文档:如果使用FILE_FLAG_OVERLAPPED打开hFile参数,则需要指向OVERLAPPED结构的指针,否则它可以为NULL。
如果使用FILE_FLAG_OVERLAPPED打开hFile,则lpOverlapped参数必须指向有效且唯一的OVERLAPPED结构,否则函数可能会错误地报告读取操作已完成。
请记住,MS文档会随时间更新,在编写代码时,文档可能不太清楚或不完整。
这可能是因为管道处于消息模式下。首先,消息模式管 prop 有长度前缀报头是很奇怪的,因为消息模式为您处理消息边界。在这个特定的场景中,整个消息可能已经在本地操作系统中,因此错误的同步读取总是会成功。
的确,该议定书(有一个单独的头)听起来像是被设计来使用字节流抽象,比如字节模式管道或TCP/IP连接。有可能协议最初是为字节模式管道设计的,当它不工作时,它们切换到了消息模式管道(同步
ReadFile
可能在字节模式管道上意外地表现,因为消息可能还没有完全呈现)。