Networking with the Standard Library
Networking Fundamentals
Network programming enables processes running on the same machine or across different hosts to exchange data over standardized communication protocols. Operating systems expose network communication through sockets—endpoints identified by an IP address, a transport protocol, and a 16-bit port number.
+-------------------------------------------------------------------+
| Application Layer HTTP, DNS, Redis, Custom Framing (App Code)|
+-------------------------------------------------------------------+
| Transport Layer TCP (Byte Stream) | UDP (Datagrams) |
| (std::net::Tcp*) | (std::net::Udp*) |
+-------------------------------------------------------------------+
| Network Layer IPv4 (32-bit) | IPv6 (128-bit) |
| (Ipv4Addr) | (Ipv6Addr) |
+-------------------------------------------------------------------+
| Link / Hardware Layer Ethernet, Wi-Fi, Loopback (OS Kernel) |
+-------------------------------------------------------------------+
Transport Protocols: TCP vs UDP
The Rust standard library (std::net) provides direct abstractions over the two primary transport-layer protocols: Transmission Control Protocol (TCP) and User Datagram Protocol (UDP).
| Characteristic | TCP (TcpStream, TcpListener) |
UDP (UdpSocket) |
|---|---|---|
| Connection Model | Connection-oriented (3-way handshake before data transfer) | Connectionless (send packets immediately to any address) |
| Abstraction | Continuous, unstructured byte stream (Read + Write) |
Discrete, message-bounded datagrams (send_to / recv_from) |
| Reliability | Guaranteed delivery; automatic retransmission of lost packets | Unreliable; packets may be dropped without notification |
| Ordering | Strictly ordered; bytes arrive in the exact sequence sent | Unordered; datagrams may arrive out of order or duplicated |
| Flow & Congestion Control | Built-in kernel flow window and congestion control | None (application must pace itself) |
| Typical Use Cases | HTTP/HTTPS, databases, SSH, RPC, file transfer | DNS queries, real-time voice/video, gaming telemetry, service discovery |
IP Addresses, Ports, and Loopback
Every transport socket binds or connects to a socket address (IP Address + Port):
- IP Address: Identifies the host interface on the network (e.g.,
192.0.2.10in IPv4 or2001:db8::1in IPv6). - Port (
u16): A 16-bit unsigned integer (0..=65535) that multiplexes traffic to a specific process on that host.0: Reserved as a wildcard port when binding; instructs the OS kernel to assign an unused ephemeral port automatically.1..=1023: Well-known / privileged ports (such as80for HTTP,443for HTTPS,53for DNS).1024..=49151: Registered application ports (such as5432for PostgreSQL,6379for Redis).49152..=65535: Dynamic / ephemeral ports used for short-lived client connections.
- Loopback (
127.0.0.1/::1): A virtual network interface routed entirely inside the local OS kernel without touching physical network hardware.
Ephemeral Port Assignment on Loopback
Binding a listener or socket to "127.0.0.1:0" asks the kernel to pick a free port immediately, which can then be inspected via .local_addr() for local client-server tests:
use std::io;
use std::net::TcpListener;
fn main() -> io::Result<()> {
// Port 0 requests an OS-assigned ephemeral port on the IPv4 loopback interface
let listener = TcpListener::bind("127.0.0.1:0")?;
let bound_addr = listener.local_addr()?;
println!("Bound IP: {}", bound_addr.ip());
println!("Assigned non-zero port: {}", bound_addr.port() > 0);
Ok(())
}
Bound IP: 127.0.0.1
Assigned non-zero port: true