【问题标题】:UDP packet loss in application layer at high speeds in WinRT?WinRT中高速应用层中的UDP数据包丢失?
【发布时间】:2012-11-09 15:28:52
【问题描述】:

这是我遇到的一个非常奇怪的错误,它似乎是 WinRT 框架的限制。复制这个问题的代码会占用太多空间,所以我会尽可能地描述它。在我的应用程序中,UI 由一些静态 TextBlock、一个不确定的进度条、一个确定的进度条和一个每秒更新的状态 TextBlock 组成。

当使用DatagramSocket 以高速 (~30Mbps) 下载 UDP 数据包时,网络层和应用层之间会发生严重的数据包丢失 (>60%)。我说它在应用层,因为在执行下载时运行数据包跟踪(例如netsh trace)会显示网络层正在接收的所有数据包,而应用层没有。

我只能假设 WinRT 框架无法跟上需要触发 MessageReceived 回调函数的速度。我还没有找到任何对 UDP 下载执行任何缓冲的方法。我发现接收 UDP 数据包的唯一方法是回调函数,它会为每个单独的数据包触发。

同样,这种应用层丢包发生在下载速度约为 30Mbps 时。在 10Mbps 等较慢的速度下看不到它。

有没有其他人遇到过这个问题,或者有没有人知道在执行 UDP 下载时执行缓冲的方法?

【问题讨论】:

    标签: c# network-programming udp windows-runtime winrt-xaml


    【解决方案1】:

    我已经研究这个问题大约一周了,并确定绝大多数数据包丢失是由于 UI 中存在进度条造成的。确定的进度条甚至不需要更新——它存在于 UI 中的事实足以导致严重的数据包丢失。在没有进度条的情况下,我能够将丢包率降低到大约 2%(从 >60%)。

    我还编写了一个瘦客户端来测试我的应用程序结构的其余部分没有负担的问题。瘦客户端仅使用硬编码值实现了 UDP 下载功能。即使完全没有 UI,我仍然在应用程序层看到 0.05% 的数据包丢失,所以这似乎确实是 WinRT 框架中的一个问题。当我在瘦客户端中只添加了一个不确定的进度条时,丢包率跃升至 >30%。

    除非有人知道执行 UDP 下载的接收部分的另一种方法(MessageReceived 回调除外),或者在 WinRT 框架中解决此问题之前,您似乎应该预计至少会有一些数据包丢失进行高速 UDP 下载时的网络层和应用层之间。此外,在执行 UDP 下载时不应使用进度条。

    TL;DR:不要在 WinRT 中使用带有 UDP 下载的进度条,否则会在高速下出现一些丢包。

    【讨论】:

    • “它存在于 UI 中的事实足以导致严重的数据包丢失” - 这绝对是奇怪的!是否考虑将其作为 Microsoft Connect 问题打开?
    • 真的!是的,我将把我的瘦客户端包发给他们,这样他们就可以看到它正在被复制。
    • @didierc 我所说的丢包不在网络上发生。它发生在网络层和应用层之间。 netsh 跟踪证明了这一点。应用层应该接收网络层正在接收的所有数据包。为了回答您的问题,我尝试使用 TCP 并且没有任何问题,但是 UDP 是我的这部分应用程序的要求。
    • 我不认为我的问题不太相关:它应该是您的错误报告中的一个很好的指标。但是如果 UDP 不可靠,网络堆栈是否必须有一个强有力的承诺,将它收到的所有数据包都传递给应用层?显然,WinRT 选择丢弃一些数据包以保持 UI 的响应性(这是我对您对现象描述的解释,请随意思考)。
    • 你的观点很好,你的解释听起来确实合理——尤其是在微软一再强调 WinRT 中的 UI 响应能力的情况下。但是,我们还没有在我们的其他客户端(iOS、Android、WP7 等)中遇到这个障碍。我认为如果 WinRT 允许访问输入缓冲区而不是限制每个回调访问单个数据包,则可以避免此问题。我们使用此方法在 WP7 客户端中解决了与此类似的问题,但在 WinRT 中它不是一个选项。
    猜你喜欢
    • 2015-06-30
    • 2016-07-04
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    相关资源
    最近更新 更多