Net
Networking namespaces for IP addresses, sockets, TCP, UDP, and DNS.
std.net is a namespace aggregator for owned socket handles, typed addresses,
and async TCP, UDP, and DNS helpers. The canonical APIs live in focused
submodules:
import std.net.ipaddr;
import std.net.socket;
import std.net.tcp;
import std.net.udp;
import std.net.dns;
std.net still re-exports the submodule namespaces and NetError, so
net.ipaddr.SocketAddr and net.NetError.InvalidAddress are valid. Prefer the
submodule imports in examples and application code.
Ipv4Addr, Ipv6Addr, IpAddr, and SocketAddr are copyable value types.
Use typed constructors for known addresses and parse for text input.
import std.net.ipaddr;
fn main() {
let ip = try ipaddr.Ipv4Addr.parse("127.0.0.1");
let addr = try ipaddr.SocketAddr.parse("127.0.0.1:8080");
let octets = ip.octets();
assert octets[0] == 127 as u8;
assert addr.port() == 8080 as u16;
}
IPv6 socket addresses use brackets in text form, for example [::1]:8080.
Ipv4Addr.octets() returns the four IPv4 bytes in network order; the old
octet0() through octet3() helpers are not part of the public surface.
socket.Socket is the low-level owned endpoint. It exposes descriptor access,
binding, listening, accepting, connecting, raw send and receive operations, and
address queries. fd() borrows the descriptor; take_fd() transfers
ownership.
import std.net.ipaddr;
import std.net.socket;
async fn main() {
let server = try socket.Socket.open(.Ipv4, .Stream);
try server.bind(ipaddr.SocketAddr.localhost(0 as u16));
try server.listen(128);
let peer = try await server.accept();
_ = peer.fd();
}
tcp.TcpListener accepts tcp.TcpStream values. tcp.TcpStream implements
aio.Stream, so it works with generic std.aio helpers.
import std.net.ipaddr;
import std.net.tcp;
async fn main() {
let listener = try tcp.TcpListener.bind(ipaddr.SocketAddr.localhost(0 as u16));
let addr = try listener.local_addr();
let accepted = listener.accept();
let stream = try await tcp.TcpStream.connect(addr);
let peer = try await accepted;
try peer.shutdown();
try stream.shutdown();
}
UDP remains datagram-oriented: send_to and recv_from carry peer addresses,
while connected UDP uses connect, send, and recv.
import std.bytes;
import std.net.ipaddr;
import std.net.udp;
async fn main() {
let socket = try udp.UdpSocket.bind(ipaddr.SocketAddr.localhost(0 as u16));
let addr = try socket.local_addr();
_ = try await socket.send_to(bytes.Bytes("x"), addr);
}
dns.resolve(host, port) runs on the runtime resolver worker and returns
future.Future<Array<ipaddr.SocketAddr> throws(io.IOError | AllocError)>.
Callers choose an address or apply their own retry and IPv4/IPv6 policy.
import std.net.dns;
async fn main() {
let addrs = try await dns.resolve("localhost", 80 as u16);
_ = addrs.length;
}
Runtime socket failures are reported as io.IOError; parse-time address
failures use net.NetError.InvalidAddress or net.NetError.InvalidPort.
| Namespace | Main items | Purpose |
|---|---|---|
std.net.ipaddr | AddressFamily, Ipv4Addr, Ipv6Addr, IpAddr, SocketAddr | Typed address values and parsing. |
std.net.socket | SocketKind, Socket | Low-level owned socket endpoint. |
std.net.tcp | TcpListener, TcpStream | Async TCP listener and stream handles. |
std.net.udp | UdpSocket | Async UDP socket operations. |
std.net.dns | resolve | Async host resolution. |
std.net | submodule namespaces, NetError | Aggregator and shared networking errors. |
Flat names such as net.SocketAddr, net.TcpStream, net.UdpSocket, and
net.resolve are no longer the documented API.