【发布时间】:2011-02-09 08:57:12
【问题描述】:
我有一个使用 UDP 与同一程序的其他实例通信的网络软件。由于不同的原因,我必须在这里使用 UDP。
我最近在通过 UDP 发送大量数据时遇到了问题,我不得不实施一个分片系统来将我的消息分成小数据块。到目前为止,它运行良好,但是当我必须发送 很多 数据块时,我现在遇到了问题。
我有以下算法:
- 将消息拆分成小的数据块(大约 1500 字节)
- 遍历数据块列表并为每个块使用
sendto()发送它
但是,当我发送大量数据块时,接收方只能收到前 6 条消息。有时它会错过第六个而收到第七个。视情况而定。
无论如何,sendto() 总是表示成功。当我通过环回接口 (127.0.0.1) 测试我的软件时总是会发生这种情况,但从不在我的 LAN 网络上测试。
如果我在sendto() 之间添加类似std::cout << "test" << std::endl; 的内容,则接收到每一帧。
我知道 UDP 允许丢包,并且我的帧可能由于多种原因而丢失,我想这与我发送数据块的速率有关。
这里的正确方法是什么?
- 实现一些确认机制(就像 TCP)似乎有点过头了。
- 在
sendto()之间添加一些任意等待时间是丑陋的,并且可能会降低性能。 - 增加(如果可能的话)接收方 UDP 内部缓冲区?我什至不知道这是否可能。
- 还有别的吗?
我真的需要你的建议。
非常感谢。
根据要求提供其他信息
我必须使用 UDP 的原因是因为我有几个限制:
- TCP 不能很好地在 NAT 遍历中工作(至少在没有特定配置的情况下)
- 某些消息可能丢失。有些人不能。
- 消息传递顺序无关紧要。
【问题讨论】:
-
TCP 的设计目的不是为了成为重量级的。它旨在满足一个明确的要求:可靠、有序的数据包传送。如果你想要同样的保证,那么就没有捷径,没有你可以实现的 TCP-light 来代替 TCP。无论您做什么,本质上都是 TCP,只会有更多错误。
-
@Marcelo 是的,我完全同意。这正是我想避免重新实现轮子的原因。
-
你有一个特别糟糕的 NAT 路由器吗?发送周期性心跳可以解决大多数 NAT 问题。
-
我不明白 TCP 不能很好地与 NAT 遍历一起工作。 UDP 更难跨 NAT 工作。
-
@nos 我的项目必须适用于几乎所有可能的配置,而不仅仅是我的。我已经有一个心跳系统来维持 UDP“连接”。
标签: c sockets udp portability sendto