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