Hyper-V:通过命名管道连接 VM 会丢失数据

Posted

技术标签:

【中文标题】Hyper-V:通过命名管道连接 VM 会丢失数据【英文标题】:Hyper-V: Connecting VMs through named pipe loses data 【发布时间】:2011-02-11 20:11:27 【问题描述】:

我们正在尝试通过串行端口连接两个 Hyper-V 虚拟机。 Hyper-V 将串行端口作为命名管道公开给主机系统,并实现命名管道的服务器端。因此,为了连接它们,我们需要编写一个命名管道客户端来连接两个虚拟机,并来回复制数据。

We have written such an application。很遗憾,此应用会丢失数据

如果我们连接两个超项,让它们交换数据,有时会传输成功,但很多情况下,接收端会报错,或者传输只是死锁。同样,如果我们使用该链接来运行内核调试器,它似乎也经常挂起。

数据丢失的原因可能是什么?以这种方式连接命名管道时有哪些注意事项?

编辑:我们已经使用kdsrv.exe 解决了这个问题。调试器的 COM 端口继续通过命名管道公开,但是,调试器端通过 TCP 与 kdserv 通信。

【问题讨论】:

【参考方案1】:

数据丢失不是由于命名管道。事实上,COM 端口(模拟的和物理的)可能会丢失数据,因为它们在 UART 中使用一个小缓冲区。

命名管道接收写入 COM 端口的所有数据。您的程序从命名管道读取数据并将其写入另一个命名管道。如果写入速度过快,接收 COM 端口的 UART 可能会溢出导致数据丢失,这就是数据丢失的原因。

您可能需要添加一些延迟以避免超过接收方预期的波特率。

此外,您的程序中缺少ResetEvent() 调用。

对于您的 KD 问题,您可能需要将 resets=0 添加到连接字符串中。

【讨论】:

感谢您的建议。限制转发有一点帮助;一个普通的“copy foo.txt COM1:”现在可以成功传输所有数据。不幸的是,HyperTerm 在 zmodem 通信中仍然会死锁,所以一定会有数据丢失的地方。至于 ResetEvent:它具体在哪里丢失?异步 IO 被定义为在 ReadFile 和 WriteFile 中正确重置事件。明天将测试 resets=0。 我的错误。不需要 ResetEvent。 这个答案并不能完全解决问题,只能部分解决。尽管如此,这是我们得到的最佳答案,所以我奖励它。请参阅我的编辑,了解我们如何解决该问题。【参考方案2】:

我没有尝试通过串行连接虚拟机,但我通过 USB 连接了虚拟机和主机(通过网络) 它有效。 如果您的软件需要建立串行连接,请尝试通过串行仿真器进行测试,并通过 tcp\ip 工作。

【讨论】:

感谢您的建议。不幸的是,真正的应用程序是这里的内核调试器,它不适用于客户机中的任何类型的网络。【参考方案3】:

我认为 John 的建议是正确的 - 如果您使用慢速 CPU 来模拟两个 VM,那么客户操作系统的串行端口驱动程序将与高速版本高度偏离。所以 John 的建议是将串行链路的输入/输出端设置为尽可能低的速度。即,您不能使用高波特率进行 VM 间串行通信。相反,您必须使用最慢的速度,以便 VM 来宾驱动程序会接受该提示并使用较慢版本的驱动程序。但是您的物理机必须有足够的 CPU 速度来同时运行两个 VM,以避免串行驱动程序的“仿真漂移”。

嗯,只是我的猜测,但是有一个 VirtualBox 版本的问题,运行它似乎没有问题:

http://bodocsi.net/2011/02/how-setup-serial-port-link-in-virtualbox-between-two-guest-virtual-machine-in-linux/

但 VirtualBox 的以下错误单确实描述了与您的问题的许多相似之处:

https://www.virtualbox.org/ticket/1548

阅读结尾似乎表明解决方案与 VirtualBox 的内部源代码有关。也许是 Hyper-V 的问题?

【讨论】:

以上是关于Hyper-V:通过命名管道连接 VM 会丢失数据的主要内容,如果未能解决你的问题,请参考以下文章

将VM的端口号映射到命名管道

Hyper-v 虚拟机使用NAT方式连接网络

当阅读器断开连接时,命名管道 (FIFO) 数据会去哪里?

命名管道在后台等待客户端,直到客户端连接

SqlConnection 卡在命名管道上

windows命名管道