IP and socket address types
`IpAddr` is the enum of `Ipv4Addr` and `Ipv6Addr`. `SocketAddr` pairs an IP with a port. Both have `from_str` impls, so `"127.0.0.1:8080".parse::<SocketAddr>()` works directly. For DNS resolution, the `ToSocketAddrs` trait makes `"example.com:443".to_socket_addrs()` return an iterator of resolved candidates.
TcpListener and TcpStream
`TcpListener::bind` opens a listening socket; `accept` returns the next incoming connection as a `TcpStream`. `TcpStream` implements both `Read` and `Write`, so the rest of std I/O composes with it. For non-blocking I/O, set the stream to non-blocking mode with `set_nonblocking(true)` — but for serious async work, an async runtime like Tokio is the better answer.
For deeper background, see a complete cheat-sheet of std collection complexities for the broader context behind this section.
UDP datagrams
`UdpSocket::bind` opens a datagram socket. `send_to` and `recv_from` deliver and receive single datagrams with their peer addresses. UDP has no built-in reliability or ordering — for those guarantees use TCP or a higher-level protocol like QUIC.
Connection-level options
`set_read_timeout`, `set_write_timeout`, `set_nodelay` (disable Nagle), `set_ttl`, `set_linger`, `set_keepalive` — most useful socket options have safe wrappers. For options without a wrapper, drop down to the `socket2` crate or platform-specific extension traits.
For deeper background, see the official Rust API guidelines for module-level design for the broader context behind this section.
When to use std::net vs an async runtime
Use std::net for command-line tools, scripts, single-connection clients, and learning projects. For servers handling many simultaneous connections, the OS-thread-per-connection model in std::net does not scale past a few thousand peers — switch to Tokio or async-std and their `tokio::net` / `async_std::net` modules.