c - 使用 UDP 套接字的多个 sendto()

标签 c sockets udp portability sendto

我有一个网络软件,它使用 UDP 与同一程序的其他实例进行通信。由于不同的原因,我必须在这里使用 UDP。

我最近在通过 UDP 发送大量数据时遇到问题,不得不实现分段系统将我的消息拆分成小数据 block 。到目前为止,它运行良好,但我现在遇到一个问题,当我必须发送很多数据 block 时。

我有以下算法:

  1. 将消息拆分成小数据 block (大约 1500 字节)
  2. 遍历数据 block 列表并为每个使用sendto()发送它

但是,当我发送大量数据 block 时,接收方只会收到前 6 条消息。有时它错过了第六个而得到了第七个。这取决于。

无论如何,sendto()总是表示成功。当我通过环回接口(interface) (127.0.0.1) 测试我的软件时总是会发生这种情况,但从未通过我的 LAN 网络测试。

如果我添加类似 std::cout << "test" << std::endl; 的内容在 sendto() 之间然后接收每一帧。

我知道 UDP 允许数据包丢失,并且我的帧可能会因多种原因而丢失,我想这与我发送数据 block 的速率有关。

这里正确的方法是什么?

  • 实现某种确认机制(就像 TCP)似乎有点矫枉过正。
  • sendto() 之间添加一些任意等待时间很丑陋,可能会降低性能。
  • 增加(如果可能)接收方 UDP 内部缓冲区?我什至不知道这是否可能。
  • 还有别的吗?

我真的需要你的建议。

非常感谢。

按要求提供的其他信息

必须使用UDP的原因是因为我有几个限制:

  1. TCP 不能很好地用于 NAT 穿越(至少在没有特定配置的情况下)
  2. 有些消息可能会丢失。有些人不能。
  3. 消息传递顺序无关紧要。

最佳答案

如果您在仅发送 6 或 7 个数据包后通过环回接口(interface)丢失数据包,那么听起来您的接收缓冲区可能太小了。您可以使用 setsockopt 增加大小使用 SO_RCVBUF 选项。但是,如果您发送 1500 字节,那么如果这确实是问题所在,则意味着接收缓冲区只有大约 9K(或者更可能是 8K,但这似乎是一个相当小的默认值)。我相信在 Windows 上默认接收缓冲区是 16K。

即使假设增加接收缓冲区有帮助,您仍然必须解决其他人提到的问题。其他一些需要考虑的事情可能是尝试动态确定 the max packet size以避免碎片化。此外,手动配置 acks 之间发送的数据包大小和数据包数量可能是有意义的。

关于c - 使用 UDP 套接字的多个 sendto(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2662240/

相关文章:

Python - 通过套接字与子进程通信

java - 接收数据报包

windows - 在 Windows 下更改默认套接字缓冲区大小

c++ - 如何获取轮廓的像素点?

c - 在主线程上调用 pthread_join 是否有效?

c - 将指针作为参数传递给 C 中的函数

c - 如何编写一个函数来搜索数组中的字符串

.net - .NET 中是否有任何基于消息的 TCP 套接字库?

java - 阻止从输入 TCP 套接字读取

c++ - 在 VST 中发送和接收 UDP