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

pftdvrlh  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(240)

我正在编写一个使用UDP发送和接收包的应用程序。然而,recv_from的文档指出:
如果消息太长,无法放入提供的缓冲区,则可能会丢弃多余的字节。
有没有办法接收所有字节并将它们写入向量?我真的必须分配一个具有最大包长度的数组(据我所知,对于IPv4是65,507字节)以确保接收所有数据?这对我来说似乎有点多。

bihw5rsg

bihw5rsg1#

查看文档中的下一个方法UdpSocket::peek_from(着重号是我的):
在套接字上接收单个数据报消息,而不将其从队列中删除
你可以用这个方法读取一个已知的固定数量的数据,比如包含整个数据包长度的报头,你可以用像byteorder这样的crates来解码报头的适当部分,用它来分配正确的空间量,然后调用recv_from
这确实要求您正在实现的协议始终在已知位置提供总大小信息。
这是个好主意吗
正如ArtemGr所说:
因为额外的系统调用比从堆栈中获取一些空间要昂贵得多。
the linked question开始:
显然,在某些时候,你会开始怀疑,为了保存内存而加倍系统调用的次数是否值得,我认为这是不值得的。
随着最近的幽灵/崩溃事件,现在是一个很好的时间来提醒,以避免额外的系统调用。
你可以像建议的那样,提前分配一个“足够大”的数组,但是你需要跟踪你实际读取了多少字节,我推荐像arrayvec这样的东西来简化它。
你可以在堆上实现一个预先分配的缓冲池。当你从套接字读取时,你使用一个缓冲区或创建一个新的。当你使用完这个缓冲区后,你把它放回缓冲池中重新使用。这样,你只需要分配一次内存,并且只需要在堆栈上传递一个小的Vec
另见:

相关问题