【问题标题】:Go: How to receive a whole UDP DatagramGo:如何接收整个 UDP 数据报
【发布时间】:2021-10-16 21:08:26
【问题描述】:

我的问题:使用 net.Read... 方法只复制给定字节数组或切片大小的字节数。我当然不想每次都分配最大 64 kB 的 UDP 数据报。

是否有go的方式来确定数据报的大小(在数据报头中)或再次读取直到数据报被完全读取?

【问题讨论】:

标签: go udp


【解决方案1】:

试试ReadFromUDP:

func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error)

ReadFromUDP 从 c 读取一个 UDP 数据包,将有效负载复制到 b。它返回复制到 b 中的字节数和数据包上的返回地址。

数据包大小应该可以从n 获得,然后您可以使用它来定义一个自定义切片(或其他数据结构)来存储数据报。这依赖于数据报大小在会话期间不会改变,它真的不应该。

【讨论】:

  • 问题是:数据报大小发生变化,我实现了 OSC(www.opensoundcontrol.org)——这不是我的决定。我从未在野外见过大于 1024 字节的 OSC 数据报,但理论上...
  • 不,它不像@0x434D53 想要的那样工作。我一直在寻找同样的东西。我需要的是标题中的第 5 和第 6 个字节。这是一个 16 位的数字,最大值为 65536 - 8。我花了一些时间查看代码,但它对 linux 内部的深入了解。仅为标头分配 8 个字节就足以知道数据包真正需要的缓冲区大小。
【解决方案2】:

通常在 UDP 协议中数据包的大小是预先知道的,并且通常要小得多,大约为 1.5k 或更小。

你可以做的是为所有读取预先分配一个最大大小的静态缓冲区,然后一旦你知道你从套接字读取的数据报的大小,分配一个具有实际大小的字节数组并将数据复制到它。我不认为你可以对同一个数据报进行额外的读取。

【讨论】:

  • 谢谢,确实害怕。我完全想避免这一额外的复制步骤。
猜你喜欢
  • 2011-03-30
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
  • 2020-08-29
  • 2021-08-02
相关资源
最近更新 更多