gpt4 book ai didi

c++ - "Correct"发送 UDP 数据报序列的方式?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:12:36 27 4
gpt4 key购买 nike

我的印象是 UDP 的不稳定性是物理层的一个属性,但似乎不是:

我正在尝试通过 UDP 发送消息,它被分成一系列数据包。消息识别和重新排序是隐式完成的。

我在同一台计算机上运行的两个应用程序上测试了此方法,并希望它能顺利运行。然而,即使数据传输完全在同一台机器上的两个程序之间进行,也存在丢包的情况,而且也很频繁。丢失似乎也很随机:有时整个消息都通过了,有时没有。

现在,即使在同一台机器上也会发生损失,这让我想知道我是否做对了?

最初,我是在一次发送中异步发送消息的所有片段,而不是等待一个片段完成再发送下一个片段。

然后,我尝试从前一条消息的完成例程中发送下一条消息。这确实提高了丢包率,但并没有完全阻止它。

如果我在这些片段之间添加一个暂停 (Sleep(...)),它会 100% 有效。

编辑:正如回答者所建议的那样:数据包发送得太快,操作系统的缓冲最少。这是合乎逻辑的。

所以,如果我想阻止向系统添加确认和重新传输(那时我可以只使用 TCP),我应该怎么做?在不将数据速率降低到本来可以更高的水平的情况下,提高丢包率的最佳方法是什么?

编辑 2:我突然想到问题可能不完全是缓冲区溢出,而不是缓冲区不可用。我正在使用 async WSARecvFrom 来接收,据我所知,它采用一个缓冲区,覆盖默认的操作系统缓冲区。当接收到数据报时,它被送入缓冲区,无论缓冲区是否已满,都会调用完成例程。

此时,根本没有缓冲区来处理传入数据,直到从完成例程中重新调用 WSARecvFrom。

问题是是否有办法创建某种缓冲池,以便在处理不同的缓冲区时可以缓冲数据?

最佳答案

在您的情况下,您只是发送数据包的速度太快,以至于接收进程无法读取它们。 O/S 在开始丢弃之前只会缓冲一定数量的接收数据包。

避免这种情况的最简单机制是让接收进程发回一个最小的 ACK 数据包,但无论它是否在几毫秒左右的时间内没有收到 ACK,发送进程都会继续。

编辑 - 本质上,UDP 是“即发即忘”。协议(protocol)中没有像 TCP 那样内置反馈机制。调整传输速率的唯一方法是让远端告诉您它没有接收到整个流。另见 RFC 2309 .


回复:数据包序列 - 由于物理层,不会发生重新排序,通常是因为 IP 网络是“数据包交换”而不是“电路交换”。

这意味着每个数据包可能会采用不同的路由通过网络,并且由于这些不同的路由可能具有不同的延迟,因此数据包可能会乱序到达。

实际上,如今很少有数据包因物理层错误而丢失。数据包丢失是因为它们以高于管道可容纳的速率发送到有限吞吐量管道中。缓冲可以通过平滑数据包流率来帮助实现这一点,但如果缓冲区已满,您又回到了原点。

关于c++ - "Correct"发送 UDP 数据报序列的方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/887797/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com