Overview
TCP sockets, TLS client sessions, and DNS resolution over a background reactor.
Four types with one job each: Dns turns a name into an address,
TcpStream.connect() opens a connection, TcpListener waits for one, and
TlsStream upgrades a connected stream to TLS. Importing the module
opens nothing and reads nothing.
Bytes are Int values from 0 to 255, one per octet. Nothing here decodes
text: encode a request line or a JSON body yourself before write(), and
decode after read(). The encoding belongs to the protocol you are
speaking, not to the socket.
The sockets are non-blocking, but the calls are not. A call that has to
wait parks the calling thread: one reactor thread keeps every socket in
the kernel poll set, and the calling thread sleeps on a condition
variable until the reactor hands back a result. Nothing spins and other
threads keep running, but the thread that called read() executes
nothing else until that read finishes.
Two consequences are worth stating plainly. There is no timeout anywhere
in this module and no way to cancel a parked call, so a peer that
connects and then goes quiet holds the calling thread for as long as it
keeps the socket open; close the stream from another thread to unblock
it, and the parked call rejects. And the promise a call returns is
already settled when the call returns, so await on it returns or throws
immediately: the wait happened inside the call.
One reader and one writer per stream, one accepter per listener. The reactor keeps a single read buffer per socket, so two readers race for the same bytes and two writers interleave theirs.
Failures reject with a String message such as connect failed: ... or
recv failed: .... The exception is TcpListener.bind, which throws
because it never waits. There is no exception type to match on, so code
that must tell failures apart has to look at the message.
write() sends one byte per reactor round trip. That keeps the socket
code simple and makes backpressure automatic, but it makes bulk payloads
slow: 4 KiB costs 4096 reactor wakeups.
None of this exists on WebAssembly. That target has no reactor, so
lookups reject with DNS resolution is unsupported in WebAssembly,
bind throws Server sockets are unsupported in WebAssembly, and every
other call reports that networking is not supported.
import { Dns } from "@std/net";
let ip = await Dns.lookup("127.0.0.1");
print(ip);When to use it
Reach for @std/net when a program touches the network directly: TcpStream.connect for clients, TcpListener.bind plus accept for servers, TlsStream for encrypted sessions, Dns.lookup for resolution. Every operation parks in the kernel until ready; nothing spins.
Capabilities
- TcpStream connect/read/write
- TcpListener bind/accept
- TlsStream sessions
- Dns.lookup
Symbols
- class Dns — Name resolution, one address per call. The only item here that works
- class TcpListener — A bound socket that hands out connected
TcpStreams. - class TcpStream — A connected TCP socket. Both peers look the same: the client gets one
- class TlsStream — A TLS client session layered over a connected
TcpStream.