如何使用UdpSocket接收任意长度的数据?

时间:2018-01-17 06:27:10

标签: network-programming rust udp

我正在编写一个使用UDP发送和接收包的应用程序。但是,documentation of recv_from州:

  

如果消息太长而无法容纳在提供的缓冲区中,则可能会丢弃多余的字节。

有没有办法接收所有字节并将它们写入向量?我是否真的必须分配一个具有最大数据包长度的数组(据我所知,对于IPv4来说是65,507字节),以确保接收所有数据?这对我来说似乎有点多了。

1 个答案:

答案 0 :(得分:1)

查看文档中的下一个方法UdpSocket::peek_from(强调我的):

  

在套接字上接收单个数据报消息,而不将其从队列中删除

您可以使用它来读取固定数量的数据,例如包含整个数据包长度的前4个字节。您可以使用byteorder将长度作为数字,然后分配恰当的空间并调用recv_from

现在,这是个好主意吗?

作为ArtemGr states

  

因为额外的系统调用比从堆栈中获取一些空间要昂贵得多。

来自the linked question

  

显然,在某些时候你会开始想知道将系统调用数量加倍以节省内存是否值得。我认为不是。

随着最近的Spectre / Meltdown活动,现在是提醒我们避免额外系统调用的好时机。

你可以按照建议只分配一个足够大的"数组提前。您需要跟踪您实际读取的字节数与已分配的字节数。我推荐像arrayvec之类的东西来简化它。

您可以在堆上实现预分配缓冲池。从套接字读取时,使用缓冲区或创建新缓冲区。完成缓冲后,将其放回池中以便重复使用。这样,你就会产生一次内存分配,并且只会在堆栈上传递小Vec个。

另见: