如何使用 UdpSocket 接收任意长度的数据?
How do I receive arbitrary length data using a UdpSocket?
我正在编写一个使用 UDP 发送和接收数据包的应用程序。但是,documentation of recv_from
指出:
If a message is too long to fit in the supplied buffer, excess bytes may be discarded.
有没有办法接收所有字节并将它们写入向量?我真的必须分配一个具有最大数据包长度的数组(据我所知,对于 IPv4 是 65,507 字节)以确保接收所有数据吗?这对我来说似乎有点多。
查看文档中的下一个方法,UdpSocket::peek_from
(强调我的):
Receives a single datagram message on the socket, without removing it from the queue.
您可以使用它来读取固定数量的数据,例如包含整个数据包长度的前导 4 个字节。您可以使用 byteorder 获取长度作为数字,然后分配恰好正确数量的 space 并调用 recv_from
.
现在,这是个好主意吗?
作为:
Because extra system calls are much more expensive than getting some space from the stack.
并且来自 the linked question:
Obviously at some point you will start wondering if doubling the number of system calls to save memory is worth it. I think it isn't.
由于最近的 Spectre / Meltdown 事件,现在是提醒避免额外系统调用的好时机。
您可以像建议的那样,提前分配一个 "big enough" 数组。您需要跟踪实际读取的字节数与分配的字节数。我推荐 arrayvec 之类的东西以使其更容易。
您可以改为在堆上实现一个预先分配的缓冲区池。当您从套接字读取时,您使用缓冲区或创建一个新缓冲区。使用完缓冲区后,将其放回池中以供重复使用。这样一来,您将进行一次内存分配,并且只会在堆栈上传递小的 Vec
s。
另请参阅:
- How large should my recv buffer be when calling recv in the socket library
- How to read UDP packet with variable length in C
我正在编写一个使用 UDP 发送和接收数据包的应用程序。但是,documentation of recv_from
指出:
If a message is too long to fit in the supplied buffer, excess bytes may be discarded.
有没有办法接收所有字节并将它们写入向量?我真的必须分配一个具有最大数据包长度的数组(据我所知,对于 IPv4 是 65,507 字节)以确保接收所有数据吗?这对我来说似乎有点多。
查看文档中的下一个方法,UdpSocket::peek_from
(强调我的):
Receives a single datagram message on the socket, without removing it from the queue.
您可以使用它来读取固定数量的数据,例如包含整个数据包长度的前导 4 个字节。您可以使用 byteorder 获取长度作为数字,然后分配恰好正确数量的 space 并调用 recv_from
.
现在,这是个好主意吗?
作为
Because extra system calls are much more expensive than getting some space from the stack.
并且来自 the linked question:
Obviously at some point you will start wondering if doubling the number of system calls to save memory is worth it. I think it isn't.
由于最近的 Spectre / Meltdown 事件,现在是提醒避免额外系统调用的好时机。
您可以像建议的那样,提前分配一个 "big enough" 数组。您需要跟踪实际读取的字节数与分配的字节数。我推荐 arrayvec 之类的东西以使其更容易。
您可以改为在堆上实现一个预先分配的缓冲区池。当您从套接字读取时,您使用缓冲区或创建一个新缓冲区。使用完缓冲区后,将其放回池中以供重复使用。这样一来,您将进行一次内存分配,并且只会在堆栈上传递小的 Vec
s。
另请参阅:
- How large should my recv buffer be when calling recv in the socket library
- How to read UDP packet with variable length in C