Linux 上的 C++:设置套接字和数据包以最小化 RTP 流延迟

Posted

技术标签:

【中文标题】Linux 上的 C++:设置套接字和数据包以最小化 RTP 流延迟【英文标题】:C++ on Linux: Setting up socket & packets for minimum RTP stream latency 【发布时间】:2013-10-01 13:50:45 【问题描述】:

我有一个 Linux 设备,它应该通过 RTP/UDP 从各种实时音频源流式传输到多个客户端,并希望实现尽可能低的延迟。它的工作方式是从各种 ALSA 接口检索帧,并使用通用 C 套接字将它们作为 RTP 流转发。

我已经使用 Wireshark 进行了一些测试,我很确定我在 IP_TOS 字段中正确设置了套接字的 DSCP 字段以进行加速转发,据我所知,这可以确保最大程度地减少这方面的延迟.

但是,我担心我没有做任何事情来将数据包标记为 VoIP,以在网络上的每个节点(使用 802.11e 标准)强制实施尽可能好的 QoS,这可能会导致更少 -超过最佳延迟。最让我怀疑的是,根据我的 Wireshark 日志,我的数据包被标记为视频数据包而不是音频/VoIP:

所以,这是我的问题:

    DSCP 与 802.11e 有何关系?我的想法是,他们在网络的不同层做不同的事情,但我不是那么了解,可能对此不以为然。

    上图是否显示任何关于数据包和/或我用来在 DSCP 或 802.11e 前端发送 RTP 流的 UDP 套接字的任何非最佳设置?

    李>

    如何使用 C++ 上的标准套接字为 VoIP 优先级标记数据包(如果可能)?

    关于我的路由器上的 802.11e,我应该注意什么特殊配置吗?我应该寻找支持 802.11e 的路由器还是已成定局?我假设 802.11e 可能与特定数据包无关,而是与路由器配置有关。

再一次,我有点迷路了,我想我可能需要有人敲打我的头,告诉我这一切是如何运作的。我可以在网上找到的所有内容似乎都与 CISCO 相关,我不确定它对我的用途有多大用处,如此处所述。

【问题讨论】:

首先,要明白除非出现拥塞,QoS 什么都不做。其次,除非数据包通过的设备被配置为在拥塞条件下处理 DSCP,否则 QoS 什么都不做(互联网上什么都不做)。第三,不同的 QoS 实现可以用 DSCP 标记做不同的事情,例如使EF 最差或最好。对于 QoS 的工作原理,没有一个答案。您根据自己的看法配置设备以确保公平,但其他人的看法不同。 【参考方案1】:
    我的理解是 QoS (ToS/DS) 八位字节是 IP 标头的第二个八位字节。 802.11e 专门用于无线网络,位于比 IP 更低的层。 对于 DiffServ 中的加速转发,我认为八位字节应该是 0xb8。我不确定这张图片是什么... 2 个八位字节? 我更熟悉 Windows,操作系统对 QoS 标记有限制。对于那些发现这篇文章的人,请查看 qwave 和 QOSCreateHandle。在 Linux 上,我猜你可以使用具有适当权限的原始套接字。 路由器可以通过几种不同的方式转换 IP QoS 八位字节...选择适合您需要的一种; DSCP 应该很常见。再次注意,这与 802.11e 不同。

其他注意事项:所有这些实际上只对您的传输机器和本地网络很重要。如果数据包离开您的网络,很可能所有 QoS 工作都将被忽略(例如,您的 ISP)。因此,除非您的本地网络出现拥塞,或者出口路由器出现拥塞,或者机器本身出现 I/O 问题,否则您的努力都是徒劳的。

【讨论】:

【参考方案2】:

我认为您设置的值不正确。

在 Linux(相对于 Windows)中,您可以直接在套接字上设置 DSCP 值:

const int IPTOS_EXPEDITED_FORWARDING = 0xb8;
const int serviceType = IPTOS_EXPEDITED_FORWARDING;      
setsockopt(sock, IPPROTO_IP, IP_TOS, (const char*)&serviceType, sizeof(serviceType));

然后你可以在Wireshark的IP级别查看:

尽管正如马克指出的那样,它可能不是很有用,因为它经常被忽略或剥离。

更糟糕的是,正如我在追踪一些神秘行为时发现的那样,它会使事情变得更糟。我的网络路径中的一些奇怪的路由器丢弃了 5-10% 的 EF 数据包,而具有空白 DSCP 值的数据包就可以了。

添加此回复以供参考,因为即使多年前提出此问题,Google 仍能找到此问题。

【讨论】:

以上是关于Linux 上的 C++:设置套接字和数据包以最小化 RTP 流延迟的主要内容,如果未能解决你的问题,请参考以下文章

如何使用ZeroMQ监听和解析特定端口上的UDP数据?

linux 中 C++ 中的 UDP Socket 编程

C ++中套接字上的协议缓冲区

如何设置 PHP 和 C++ 之间的通信?

在 C 或 C++ 中的同一个套接字上同时读取和写入

C ++套接字不接收传入数据包,在Python中工作