Rust Connected UDP
A connected UDP socket stores one peer address. An unconnected socket names the address on every packet.
Remember the peer
One call stores the address inside the socket:
client.connect(server_addr).unwrap();Send with no address
The stored peer is the destination now:
client.send(b"ping").unwrap();Receive from that peer only
recv takes no address and returns a count. Packets from strangers never reach it:
let mut buf = [0u8; 64];
let count = client.recv(&mut buf).unwrap();The open socket serves anyone
The server side stays unconnected. recv_from learns each sender, and send_to answers that sender:
let (count, sender) = socket.recv_from(&mut buf).unwrap();
socket.send_to(b"pong", sender).unwrap();Example
use std::net::UdpSocket;
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
let server = thread::spawn(move || {
let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
tx.send(socket.local_addr().unwrap()).unwrap();
let mut buf = [0u8; 64];
let (count, sender) = socket.recv_from(&mut buf).unwrap();
let text = String::from_utf8_lossy(&buf[..count]).into_owned();
socket.send_to(b"pong", sender).unwrap();
text
});
let server_addr = rx.recv().unwrap();
let client = UdpSocket::bind("127.0.0.1:0").unwrap();
client.connect(server_addr).unwrap();
client.send(b"ping").unwrap();
let mut buf = [0u8; 64];
let count = client.recv(&mut buf).unwrap();
println!("reply = {}", String::from_utf8_lossy(&buf[..count]));
let received = server.join().unwrap();
println!("server received = {received}");
}Key points
- connect() on a UDP socket sends nothing at all.
- It only stores the default peer inside the socket
- Use send and recv after connect.
- No address rides along, and recv accepts packets from that peer only
- Packets from any other sender are dropped for you on a connected socket.
- An unconnected socket accepts packets from anyone
- Serve many clients with recv_from on one unconnected socket.
- Hold one conversation with a connected socket
- On Linux, a connected socket also hears bad news fast.
- If the peer's port has closed, a later send or recv can fail with ConnectionRefused.
- An unconnected socket hears nothing
In this example, the server socket stays unconnected. It learns the client's address from the first packet, and it answers that address. The client connects first, so its send needs no address and its recv trusts only the server. Expected output shown โ this sandbox blocks UDP sends (EPERM), so the full exchange could not finish here. The program compiles cleanly. In a test run the ping did reach the server, but the reply send was refused. On an ordinary machine the two lines print as shown.
Note
Nothing was opened, so no handshake stands in the way.
Call connect again with a new address and the socket talks to the new peer.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Rust Playground
Exercise
What does connect() do on a UDP socket?