Reputation: 6626
This is the current code listening to the udpsocket at port: 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(())
}
Now, the length of my data will vary and I cannot give a size like "2048", or the buffer will run out when I send bigger data.
Can I create a dynamic size buffer (or something similar), I know that socket.send method has a length parameter, can I take advantage of that?
Upvotes: 0
Views: 1372
Reputation: 81
For anybody stumbling upon this thread: A UDP datagram has an upper size limit which is 65,507 bytes for IPv4 and 65,527 bytes for IPv6. A sufficient sized heap allocated array (Box<[u8; 65527]>
) can be used to to receive all package up to the max. size.
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(())
}
Upvotes: 0
Reputation: 3825
Now, the length of my data will vary and I cannot give a size like "2048"
Do you have packed the length information of your data into the packet data? For example, the leading 4 bytes containing the length of the entire packet.
If you have such information, you could use the UdpSocket::peek:
Receives single datagram on the socket from the remote address to which it is connected, without removing the message from input queue. On success, returns the number of bytes peeked.
Then you could get the length as a number, then allocate exactly the right amount of space and call.
But everything comes with a tradeoff, it needs an extra system call, which could be more expensive than getting some space from the stack.
Or, you could, just simply allocate a "big enough" array ahead of time.
Upvotes: 2