Rust Socket Addresses
A SocketAddr is one value that holds an IP address and a port. A SocketAddr can be built from its pieces, and its pieces can be read back out.
Turn text into an address
One parse call turns the written form into a value:
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();Read the pieces back out
println!("ip = {}", addr.ip());
println!("port = {}", addr.port());
println!("ipv4 = {}", addr.is_ipv4());Build one from pieces
No text is needed. Four bytes and a port do the job:
let built = SocketAddr::from(([127, 0, 0, 1], 8080));
println!("built = {}", built);Ask what kind of address it is
println!("v4 loopback = {}", Ipv4Addr::LOCALHOST.is_loopback());
println!("v6 loopback = {}", Ipv6Addr::LOCALHOST.is_loopback());
println!("any is unspecified = {}", Ipv4Addr::UNSPECIFIED.is_unspecified());Bind narrow or bind wide
127.0.0.1 hears only this machine. 0.0.0.0 hears every face. Its ip() reads back as unspecified:
let wide = TcpListener::bind("0.0.0.0:0").unwrap();
println!("wide bind is unspecified = {}", wide.local_addr().unwrap().ip().is_unspecified());Example
use std::net::{SocketAddr, TcpListener};
fn main() {
let texts = ["127.0.0.1:8080", "[::1]:9000", "not an address"];
for text in texts {
match text.parse::<SocketAddr>() {
Ok(addr) => println!("{text} -> ip {}, port {}, ipv6 {}", addr.ip(), addr.port(), addr.is_ipv6()),
Err(_) => println!("{text} -> not an address"),
}
}
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let local = listener.local_addr().unwrap();
println!("bound to ip {} on a free port = {}", local.ip(), local.port() > 0);
}Key points
- SocketAddr: one value that holds an IP address and a port together
- Use text.parse::<SocketAddr>() to turn written text into an address.
- Text that is not an address gives an Err
- Use addr.ip() and addr.port() to read the pieces back out
- Use SocketAddr::from(([127, 0, 0, 1], 8080)) to build an address from pieces, with no text to parse
- Binding to 0.0.0.0 claims every network face of this machine.
- Binding to 127.0.0.1 claims this machine only
In this example, three texts meet parse::<SocketAddr>(). The first is a plain IPv4 address. The second is IPv6, so it wears square brackets. The third is not an address at all. It lands in the Err arm and prints a plain message. Then a listener binds 127.0.0.1:0. Port 0 lets the system pick a free port. The program prints the chosen ip. It checks only that the port is real, not which port it is.
Note
IPv6 text wears square brackets: [::1]:8080.
The brackets keep the colons of the address apart from the colon of the port.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
What does binding a listener to 0.0.0.0 ask for?