如何在C++中以指定速率发送UDP数据包在 Windows 上?

发布于 2024-10-18 13:03:16 字数 470 浏览 1 评论 0原文

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

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

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

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

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

I'm writing a program that implements the RFC 2544 network test. As the part of the test, I must send UDP packets at a specified rate.

For example, I should send 64 byte packets at 1Gb/s. That means that I should send UDP packet every 0.5 microseconds. Pseudocode can look like "Sending UDP packets at a specified rate":

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

But I'm afraid there is no some_sleep() function in Windows, and Linux too, that can give me 0.5 microseconds resolution.

Is it possible to do this task in C++, and if yes, what is the right way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不醒的梦 2024-10-25 13:03:16

两种方法:

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

  • 允许如果速率略有变化,当您足够提前计算速率时,插入 Sleep(1)。使用 timeBeginPeriod 获得 1ms 分辨率。

对于这两种方法,您不能依赖精确的睡眠。您需要保留总数计数器并在领先/落后时调整睡眠时间。

Two approaches:

  • Implement your own sleep by busy-looping using a high-resolution timer such as windows QueryPerformanceCounter

  • Allow slight variations in rate, insert Sleep(1) when you're enough ahead of the calculated rate. Use timeBeginPeriod to get 1ms resolution.

For both approaches, you can't rely on the sleeps being exact. You will need to keep totals counters and adjust the sleep period as you get ahead/behind.

别念他 2024-10-25 13:03:16

这可能会有帮助,但我怀疑它是否可以直接移植到 Windows 以外的任何平台。 为 Windows 实现持续更新的高分辨率时间提供程序,作者:Johan Nilsson 。

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

This might be helpful, but I doubt it's directly portable to anything but Windows. Implement a Continuously Updating, High-Resolution Time Provider for Windows by Johan Nilsson.

However, do keep in mind that for packets that small, the IP and UDP overhead is going to account for a large fraction of the actual on-the-wire data. This may be what you intended, or not. A very quick scan of RFC 2544 suggests that much larger packets are allowed; you may be better off going that route instead. Consistently delaying for as little as 0.5 microseconds between each Send_UDP() call is going to be difficult at best.

爱她像谁 2024-10-25 13:03:16

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

To transmit 64-byte Ethernet frames at line rate, you actually want to send every 672 ns. I think the only way to do that is to get really friendly with the hardware. You'll be running up against bandwidth limitations with the PCI bus, etc. The system calls to send one packet will take significantly longer than 672 ns. A sleep function is the least of your worries.

盛夏尉蓝 2024-10-25 13:03:16

您猜想您应该能够使用 Boost Asio 的计时器功能来做到这一点。我自己还没有尝试过,但我猜 deadline_timer 会需要 boost::posix_time::nanosec 以及 boost::posix_time::第二

查看示例此处< /a>

You guess you should be able to do it with Boost Asios timer function. I haven't tried it myself, but I guess that deadline_timer would take a boost::posix_time::nanosec as well as the boost::posix_time::second

Check out an example here

伏妖词 2024-10-25 13:03:16

这是 nanosleep< 的本机 Windows 实现< /代码>。如果 GPL 可以接受,您可以重用该代码,否则您将不得不重新实现。

Here's a native Windows implementation of nanosleep. If GPL is acceptable you can reuse the code, else you'll have to reimplement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文