监听udpsocket时需要动态大小的缓冲区

问题描述 投票:0回答:2

这是当前监听udpsocket端口的代码:34254

use std::net::UdpSocket;
use std::str;

fn main() -> std::io::Result<()> {
    {
        let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
        socket.connect("127.0.0.1:34254").expect("connect function failed");
        println!("ready");
        let mut buf = [0; 2048];
        match socket.recv(&mut buf) {
            Ok(_received) =>{
                let s = match str::from_utf8(&buf) {
                    Ok(v) => v,
                    Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
                };
                println!("result: {}", s);
            },
            Err(e) => println!("recv function failed: {:?}", e),
        }
    } // the socket is closed here
    Ok(())
}

现在,我的数据长度会有所不同,我不能给出像“2048”这样的大小,否则当我发送更大的数据时,缓冲区将耗尽。

我可以创建一个动态大小的缓冲区(或类似的东西),我知道socket.send方法有一个长度参数,我可以利用它吗?

rust udp buffer
2个回答
2
投票

现在,我的数据长度会有所不同,我无法给出像“2048”这样的大小

您是否已将数据的长度信息打包到数据包中?例如,前 4 个字节包含整个数据包的长度。

如果您有此类信息,您可以使用 UdpSocket::peek:

在套接字上从其连接的远程地址接收单个数据报,而不从输入队列中删除消息。成功时,返回查看的字节数。

然后您可以获得数字形式的长度,然后分配正确的空间量并调用。

但是一切都需要权衡,它需要额外的系统调用,这可能比从堆栈中获取一些空间更昂贵。

或者,您可以简单地提前分配一个“足够大”的数组。


0
投票

对于任何偶然发现此线程的人:UDP 数据报的大小上限为 IPv4 的 65,507 字节和 IPv6 的 65,527 字节。足够大小的堆分配数组 (

Box<[u8; 65527]>
) 可用于接收最大数量的所有包。尺寸。

use std::net::UdpSocket;
use std::str;

fn main() -> std::io::Result<()> {
    {
        let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
        socket.connect("127.0.0.1:34254").expect("connect function failed");
        println!("ready");
        let mut buf: Box<[u8; 65527]> = Box::new([0; 65527]);
        match socket.recv(buf.as_mut_slice()) {
            Ok(n) =>{  // n is the number of received bytes
                let s = match str::from_utf8(&buf[..n]) {  // reading up to n
                    Ok(v) => v,
                    Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
                };
                println!("result: {}", s);
            },
            Err(e) => println!("recv function failed: {:?}", e),
        }
    } // the socket is closed here
    Ok(())
}
© www.soinside.com 2019 - 2024. All rights reserved.