Migrating from Sockets to Reseau
If you are porting code from Julia's stdlib Sockets, the easiest mental model is:
- keep the familiar
connect,listen,accept,read!,write, andcloseflow - move plain transport work onto
Reseau.TCP - move TLS work onto
Reseau.TLS - replace timeout wrappers with connection deadlines
- Quick Mapping
- TCP Server Shape
- Hostname-Based Dialing
- Standard I/O Still Applies
- Deadlines Become First-Class
- TLS Lives In The Same Stack
- One Naming Difference To Keep
- Porting Checklist
Quick Mapping
Sockets | Reseau |
|---|---|
listen(ip"127.0.0.1", port) | TCP.listen(TCP.loopback_addr(port)) |
connect(ip"127.0.0.1", port) | TCP.connect(TCP.loopback_addr(port)) |
connect("example.com", port) | TCP.connect("example.com:$port") |
accept(server) | TCP.accept(listener) |
read!(sock, buf) | read!(conn, buf) |
write(sock, buf) | write(conn, buf) |
close(sock) | close(conn) / close(listener) |
getsockname(sock) | TCP.local_addr(conn) |
getpeername(sock) | TCP.remote_addr(conn) |
| external TLS wrapper | TLS.connect, TLS.listen, TLS.client, TLS.server |
TCP Server Shape
Sockets
using Sockets
server = listen(ip"127.0.0.1", 9000)
sock = accept(server)
close(sock)
close(server)Reseau
using Reseau
listener = TCP.listen(TCP.loopback_addr(9000))
conn = TCP.accept(listener)
close(conn)
close(listener)Read TCP for the full connection and deadline model.
Hostname-Based Dialing
If your old code used separate host and port arguments, the most direct Reseau translation is the "host:port" string-address surface:
using Reseau
conn = TCP.connect("example.com:443")
close(conn)If you need to control family preference, timeout budget, or custom resolution, read Name Resolution.
Standard I/O Still Applies
One nice migration property is that the connection still behaves like a Julia stream:
read!(conn, buf)readbytes!(conn, buf, nb)readavailable(conn)write(conn, buf)close(conn)
The main difference is in the transport semantics: deadlines and readiness are part of the connection itself. read!(conn, buf) keeps Julia's usual exact-fill-or-EOFError behavior, while readbytes! and readavailable are the short-read helpers when you want count-returning reads.
Deadlines Become First-Class
Instead of wrapping operations in ad hoc timeout tasks, set deadlines directly on the live connection:
using Reseau
conn = TCP.connect("example.com:443")
TCP.set_read_deadline!(conn, time_ns() + 5_000_000_000)
close(conn)This deadline model carries through to TLS as well.
TLS Lives In The Same Stack
With Sockets, TLS is usually another package layered on top. With Reseau, TCP and TLS are sibling surfaces in one transport stack:
using Reseau
tls = TLS.connect(
"example.com:443";
verify_peer = true,
alpn_protocols = ["h2", "http/1.1"],
)
close(tls)For servers:
using Reseau
cfg = TLS.Config(cert_file = "server.crt", key_file = "server.key")
listener = TLS.listen("tcp", "127.0.0.1:8443", cfg)
close(listener)Read TLS for handshake behavior, config options, and lifecycle details.
One Naming Difference To Keep
Full teardown follows Base conventions: use close(conn) and close(listener).
Half-close remains explicit:
closewrite(conn)TCP.closeread(conn)
Porting Checklist
- Replace
Sockets.connect(host, port)withTCP.connect("host:port")when you want hostname resolution. - Replace listen/accept loops with
TCP.listen(...)andTCP.accept(listener). - Replace timeout wrappers with
TCP.set_deadline!,TCP.set_read_deadline!, orTCP.set_write_deadline!. - Move TLS setup onto
TLS.Config,TLS.connect,TLS.listen,TLS.client, andTLS.server. - Update any code that expected
Sockets.TCPSocketinternals; Reseau exposesTCP.ConnandTLS.Conninstead.