命名管道、ERROR_MORE_DATA 和 CancelIoEx 的重叠消息

Posted

技术标签:

【中文标题】命名管道、ERROR_MORE_DATA 和 CancelIoEx 的重叠消息【英文标题】:Overlapped message named pipe, ERROR_MORE_DATA and CancelIoEx 【发布时间】:2012-03-27 02:06:52 【问题描述】:

我第一次使用 $SUB 并遇到了这个问题。客户端和服务器都使用重叠操作,这是我遇到问题的具体情况。

客户

C1。连接到服务器。 C2。发送大于管道缓冲区的消息,并且缓冲区传递给服务器中的重叠读取操作。 C3。成功取消发送操作。

服务器

S1。创建并等待客户端。 S2。当客户端连接时,它会读取消息。 S21。因为消息不适合缓冲区(ERROR_MORE_DATA),所以它被部分读取。

在我看来,无法判断整个消息作为一个孤立的单元何时被取消。特别是,如果客户端取消发送操作,服务器不会收到整个消息,只是其中的一部分,并且随后的读取操作返回 ERROR_IO_PENDING(在我的情况下),这意味着没有要读取的数据并且读取操作已经被排队。我希望有某种方式告诉读者该消息已被取消,以便读者可以对其采取行动。

但是,相关文档分散在 MSDN 上,所以我可能会遗漏一些东西。如果有人能对此有所了解,我将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

你是对的,没有办法说。

如果您在中途取消 Writefile,则只会写入部分消息,因此服务器只会读取该部分。在您取消消息之前,没有发送关于消息大小的“簿记”信息 - 发送的只是原始数据。

所以答案是:不要取消 IO,等待它成功即可。

如果您确实需要在中途取消 IO,您可能应该切断连接并从头开始,就像网络中断一样。

(您可以检查您的 OVERLAPPED 结构以了解实际写入了多少,然后从那里继续,但如果您想这样做,您可能一开始就不会取消 IO。)

您为什么要取消 IO?哪些情况会触发此要求?

【讨论】:

我的客户端(管道编写器)有一个事件循环,除了通过管道发送消息之外,它还处理其他事情。这就是为什么管道发送是异步的,客户端不会永远阻塞,以防服务器(阅读器)在处理消息和缓冲区填满时遇到麻烦。如果发送操作是异步的,则将重叠的事件句柄添加到 WaitForMultibleObjects 调用中。 感谢您建议关闭管道。这就是我现在正在做的事情,它适用于我的情况。 @PeterVrabel 你见过MsgWaitForMultipleObjectCoWaitForMultipleHandles 吗?它们还允许您唤醒其他消息,例如用户输入。这可能会让您在需要取消 IO 之前等待更长的时间。

以上是关于命名管道、ERROR_MORE_DATA 和 CancelIoEx 的重叠消息的主要内容,如果未能解决你的问题,请参考以下文章

命名管道(C#)

管道和命名管道

windows命名管道

windows命名管道

命名管道和分叉令人头疼

Linux管道和命名管道