TcpStream
struct TcpStreamA connected TCP socket.
Owns a RawSocket and exposes blocking read/write operations.
TCP_NODELAY is set automatically on every new stream so callers
get low-latency behaviour without any configuration.
This type is Movable but not Copyable — a TCP connection
cannot be duplicated without tracking both file descriptors.
The connection is closed automatically when the struct is destroyed.
Thread safety:
Not thread-safe . Do not share a TcpStream across
threads without external synchronisation.
Example:
from flare.tcp import TcpStream
from flare.net import SocketAddr
var stream = TcpStream.connect(SocketAddr.localhost(8080))
stream.write_all("hello".as_bytes())
var buf = List[UInt8](capacity=1024)
buf.resize(1024, 0)
var n = stream.read(buf.unsafe_ptr(), len(buf))
stream.close()
Implements Movable, Readable, _ChunkWriter
__init__
def __init__(out self, var socket: RawSocket, peer: SocketAddr) Wrap an already-connected RawSocket.
Safety:
socket must be connected before calling this constructor.
TCP_NODELAY should already be set by the factory functions.
- Args
socket: An open, connected file descriptor (ownership transferred).peer: The remote address.
__deinit__
def __deinit__(deinit self) connect
def connect(addr: SocketAddr) -> Self Open a blocking TCP connection to addr.
Sets TCP_NODELAY automatically.
Example:
var stream = TcpStream.connect(SocketAddr.localhost(8080))
- Args
addr: The remote socket address to connect to.
Raises ConnectionRefused: If the remote port actively refuses. ConnectionTimeout: If the OS connect timeout expires. ConnectionReset: If the peer sends a TCP RST during connect. NetworkError: For any other OS error.
def connect(host: String, port: UInt16) -> Self Resolve host via DNS and open a blocking TCP connection.
Convenience overload that performs DNS resolution then calls
TcpStream.connect(SocketAddr(...)) automatically.
Example:
var stream = TcpStream.connect("example.com", 80)
- Args
host: Hostname or IP address string (e.g."example.com").port: TCP port number.
Raises DnsError: If host cannot be resolved.
ConnectionRefused: If the remote port actively refuses.
ConnectionTimeout: If the OS connect timeout expires.
NetworkError: For any other OS error.
def connect(host: String, port: UInt16, timeout_ms: Int) -> Self Resolve host via DNS (dual-stack) and connect with a timeout.
Tries each resolved address in order (IPv4 and IPv6), falling back to the next on failure.
- Args
host: Hostname or IP address string.port: TCP port number.timeout_ms: Maximum time to wait in milliseconds.
Raises DnsError: If host cannot be resolved.
ConnectionTimeout: If all addresses time out.
ConnectionRefused: If all addresses refuse.
NetworkError: For any other OS error.
connect_timeout
def connect_timeout(addr: SocketAddr, timeout_ms: Int) -> Self Open a TCP connection, failing if it takes longer than timeout_ms.
On macOS/arm64 this delegates to flare_connect_timeout in
libflare_tls.so to avoid a Mojo ABI bug where external_call
silently corrupts variadic-function arguments (e.g. the third argument
of fcntl) on that platform.
On Linux, the non-blocking connect + poll(POLLOUT) +
getsockopt(SO_ERROR) sequence is implemented directly via
external_call. OwnedDLHandle.get_function crashes on Linux
when calling into a freshly-loaded shared library, so the C helper
cannot be used there.
Example:
var stream = TcpStream.connect_timeout(SocketAddr.localhost(8080), 5000)
- Args
addr: The remote socket address.timeout_ms: Maximum time to wait in milliseconds (must be > 0).
Raises ConnectionTimeout: If the deadline expires before connecting. ConnectionRefused: If the port actively refuses. NetworkError: For any other OS error.
__enter__
def __enter__(var self) -> Self Transfer ownership of self into the with block.
read
def read(mut self, buf: Pointer[UInt8], size: Int) -> Int Read up to size bytes from the stream into buf.
Retries transparently on EINTR. Returns 0 on EOF (the peer
closed the connection) — this is not an error.
Example:
var buf = List[UInt8](capacity=4096)
buf.resize(4096, 0)
var n = stream.read(buf.unsafe_ptr(), len(buf))
if n == 0:
print("connection closed")
- Args
buf: Destination buffer; the caller must provide at leastsizebytes of valid storage.size: Maximum number of bytes to read.
Raises ConnectionReset: If the peer sent a TCP RST. Timeout: If a recv timeout was set and expired. NetworkError: For any other OS read error.
read_exact
def read_exact(mut self, buf: Pointer[UInt8], size: Int) Read exactly size bytes into buf.
Loops over read() until size bytes have been received.
Example:
var exact = List[UInt8](capacity=8)
exact.resize(8, 0)
stream.read_exact(exact.unsafe_ptr(), 8)
- Args
buf: Destination buffer; must have at leastsizebytes.size: Exact number of bytes to read.
Raises NetworkError: If EOF is reached before size bytes are received,
or on any other I/O error.
write
def write(self, data: Span[UInt8]) -> Int Write up to len(data) bytes to the stream.
A single call may write fewer bytes than requested (partial write).
Use write_all to guarantee all bytes are sent. Retries on
EINTR.
Example:
var n = stream.write("hello".as_bytes())
- Args
data: The bytes to send.
Raises BrokenPipe: If the peer has closed the read end. Timeout: If a send timeout was set and expired. NetworkError: For any other OS write error.
write_all
def write_all(self, data: Span[UInt8]) Write all of data, looping until every byte is sent.
Example:
stream.write_all("Hello, server!".as_bytes())
- Args
data: The bytes to send completely.
Raises BrokenPipe: If the peer closes before all bytes are sent.
NetworkError: For any other OS write error, or if send(2)
returns 0 for a non-empty buffer (no progress is possible).
peer_addr
def peer_addr(self) -> SocketAddr Return the remote socket address.
local_addr
def local_addr(self) -> SocketAddr Return the local socket address assigned by the OS.
Raises NetworkError: If getsockname(2) fails.
shutdown_read
def shutdown_read(self) Shut down the read half of the connection.
After this call, any subsequent read() returns 0 (EOF). The
peer will receive a FIN indicating no more data will be read.
Raises NetworkError: If shutdown(2) fails.
shutdown_write
def shutdown_write(self) Shut down the write half of the connection.
Sends a FIN to the peer, signalling that no more data will be
written. The peer will see EOF on their next read().
Raises NetworkError: If shutdown(2) fails.
close
def close(mut self) Close the connection explicitly. Idempotent.
set_nodelay
def set_nodelay(self, enabled: Bool) Toggle TCP_NODELAY (Nagle's algorithm).
- Args
enabled:Truedisables Nagle (low-latency);Falsere-enables it.
set_keepalive
def set_keepalive(self, enabled: Bool) Toggle SO_KEEPALIVE.
- Args
enabled:Trueto send keepalive probes on idle connections.
set_recv_timeout
def set_recv_timeout(self, ms: Int) Set a per-read timeout.
After the timeout expires, read() raises Timeout.
- Args
ms: Timeout in milliseconds. 0 disables the timeout.
set_send_timeout
def set_send_timeout(self, ms: Int) Set a per-write timeout.
After the timeout expires, write() raises Timeout.
- Args
ms: Timeout in milliseconds. 0 disables the timeout.