【问题标题】:How do I send UDP packets at a specified rate in C++ on Windows?如何在 Windows 上的 C++ 中以指定速率发送 UDP 数据包?
【发布时间】:2011-02-21 14:31:50
【问题描述】:

我正在编写一个实现 RFC 2544 网络测试的程序。作为测试的一部分,我必须以指定的速率发送 UDP 数据包。

例如,我应该以 1Gb/s 的速度发送 64 字节的数据包。这意味着我应该每 0.5 微秒发送一次 UDP 数据包。伪代码可以看起来像“Sending UDP packets at a specified rate”:

while (true) {
    some_sleep (0.5);
    Send_UDP();
}

但恐怕在 Windows 和 Linux 中都没有 some_sleep() 函数,它可以给我 0.5 微秒的分辨率。

是否可以在 C++ 中完成此任务,如果可以,正确的方法是什么?

【问题讨论】:

  • 是否需要每 0.5 us 发送 1 个数据包,还是可以尽可能快地发送 pxbmcackets,然后等到一秒钟过去?
  • 是的,我需要每 0.5 us 发送 1 个数据包,可以按照 RFC 2544 测试的推荐(但不是必需)部分单独完成数据包的非均匀流。

标签: c++ networking udp


【解决方案1】:

两种方法:

  • 通过使用高分辨率计时器(例如 windows QueryPerformanceCounter)进行忙循环来实现您自己的睡眠

  • 允许速率稍有变化,当您在计算速率之前足够多时插入 Sleep(1)。使用 timeBeginPeriod 获得 1ms 的分辨率。

对于这两种方法,您都不能依赖准确的睡眠。您需要保留总计计数器并在前进/后退时调整睡眠时间。

【讨论】:

    【解决方案2】:

    这可能会有所帮助,但我怀疑它是否可以直接移植到 Windows 以外的任何设备上。 Implement a Continuously Updating, High-Resolution Time Provider for Windows Johan Nilsson。

    但是,请记住,对于这么小的数据包,IP 和 UDP 开销将占实际在线数据的很大一部分。这可能是你想要的,也可能不是。对 RFC 2544 的快速扫描表明允许更大的数据包;你最好走那条路。在每次Send_UDP() 调用之间持续延迟低至 0.5 微秒是最困难的。

    【讨论】:

    • 添加到 Michael 的观察中,除了由于 TCP/UDP 标头导致的 28 字节开销之外,由于以太网帧,您还将有 38 个额外的八位字节的开销。结果,线路上实际输出的字节为 38+28+64=130 字节。此外,您的实际传输速率将取决于您使用的以太网上的负载。这是什么意思呢?小心。
    • RFC 2544 指定了一个 64 字节的以太网帧大小(用于测试允许的最小帧大小)。这意味着(18 字节有效载荷 + 8 字节 udp 报头 + 20 字节 IP 报头 + 14 字节以太网报头 + 4 字节 FCS)+ 20 字节 IFG+前导码+SOF = 84 字节或 672 位 => 672 ns(以 GbE 速率)。跨度>
    • 感谢您提供的链接,它非常有用。
    【解决方案3】:

    要以线速传输 64 字节以太网帧,您实际上希望每 672 ns 发送一次。我认为做到这一点的唯一方法是对硬件真正友好。您将遇到 PCI 总线等的带宽限制。发送一个数据包的系统调用将花费比 672 ns 长得多的时间。睡眠功能是您最不必担心的问题。

    【讨论】:

    • 感谢您的回答。在不与硬件友好的情况下,我可以发送的最小数据包大小是多少?
    • 嗯,这取决于。如果您尝试在软件中执行此操作,则会涉及与您无法直接控制的其他进程共享的大量资源(总线/cpu/中断处理程序/等)。了解给定系统的最佳方法是测试。您可以循环发送数据包并计算在几分钟内发送了多少。根据数据包大小,确定您与线路速率的接近程度。调整数据包大小,然后重试。做一堆不同的跑步;你会学到很多东西。
    【解决方案4】:

    你猜你应该可以用Boost Asios 定时器功能来做到这一点。我自己没有尝试过,但我猜deadline_timer 会采用boost::posix_time::nanosec 以及boost::posix_time::second

    查看示例here

    【讨论】:

      【解决方案5】:

      Here'snanosleep 的本机 Windows 实现。如果 GPL 可以接受,您可以重用代码,否则您必须重新实现。

      【讨论】:

        猜你喜欢
        • 2022-01-19
        • 2011-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-24
        • 2011-06-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多