socket
A small wrapper around BSD/POSIX TCP sockets, in the spirit of Python's socket module. Two layers are available: a flat, file-descriptor API (like the C layer — you pass the integer fd from socket() / tcp_listen() / accept() to the other calls), and, on top of it, owning guards (socket.open, socket.serve) that return Conn/Listener values whose destructors close the fd — use them with with so a connection or listener can't leak (see below). IPv4 + TCP only; hosts are resolved with getaddrinfo, so "localhost", "127.0.0.1", and DNS names all work.
import io
import socket
let lfd = socket.tcp_listen("127.0.0.1", 8080, 16) # create + bind + listen
io.print("listening on", socket.local_port(lfd))
let conn = socket.accept(lfd) # wait for a client
let request = socket.recv(conn, 8192)
socket.sendall(conn, "HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nhi")
socket.close(conn)
socket.close(lfd)What's here
Owning guards (RAII,
with-friendly) —open(host, port)→ aConn, andserve(host, port, backlog)→ aListener; each closes its fd on scope exit.Convenience —
tcp_listen(host, port, backlog),tcp_connect(host, port).Per-connection I/O —
accept,recv,send,sendall,close, plusset_timeout(fd, ms)(recv/send deadlines) andshutdown(fd)(half-close).Low-level BSD —
socket,set_reuseaddr,bind,listen,connect,local_port, andlast_error(the currenterrnotext).
import io
import socket
with socket.serve("127.0.0.1", 8080, 16) as server { # a Listener guard
io.print("listening on", server.local_port())
with server.accept() as conn { # a Conn guard for the client
let request = conn.recv(8192)
conn.sendall("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nhi")
} # conn closed here, on every path
} # server closed hereErrors are reported as a negative return (or "" from recv); call last_error() for the message. send uses MSG_NOSIGNAL, so a broken pipe never raises a signal. Only recv and last_error allocate (their returned string).
Throughput tuning (default on every connected socket)
Every socket returned by connect/tcp_connect and accept is tuned for bulk transfer with no caller opt-in: TCP_NODELAY (Nagle off), TCP_QUICKACK (prompt ACKs — re-armed after each recv, since Linux clears it), and an enlarged SO_RCVBUF/SO_SNDBUF. Without these a pure download sits in delayed-ACK slow start — one segment per round-trip — which crawls even though the CPU is idle. Guarded so getsockopt proves the options on both ends (socket_test.cpp ConnectedSocketsAreTunedByDefault).
Measured against known-fast references with scripts/net_bench_compare.sh and scripts/tls_loopback_bench.sh:
On a throttled WAN link a cheatah HTTPS GET ties curl on the identical URL — both are pinned by the throttle, so the download path is not the limiter.
Throttle-free over loopback against a real
openssl s_server(byte-identity verified) curl is still ahead; the gap is per-record TLS framing (copies + per-record key re-expansion), not the cipher — cheatah AES-128-GCM sits at parity with OpenSSL in the crypto table. Closing the framing gap only matters on links faster than any real one and is tracked as evidence-gated follow-up.
Secure clients are built on this: the from-scratch tls 1.3 client rides a connected socket, and requests (pure cheatah) and websocket are layered on top. Plain http:// works directly here.
Per-function docs (parameters, runtime complexity, heap behavior) are in socket.hpp. Tested in ../tests/socket_test.cpp (real loopback round-trips); ASan + Valgrind clean via the QA gate (security/run-valgrind.sh).
Classes
Conn— An owning TCP connection — a socket fd whose destructor closes it.Listener— An owning listening socket; accept() yields owning Conn clients; the destructor closes it.
Functions
Create an IPv4 TCP socket.
Allocates an unbound, unconnected AF_INET/SOCK_STREAM fd; you must follow up with bind()+listen() or connect() before it can carry data, and close() it when done.
the new fd, or -1 on error.
O(1).
none.
CheatahSocket.ListenLowLevelSocketCompileRun.SocketStdlibE2E.SocketEnable SO_REUSEADDR on fd.
Lets a subsequent bind() reuse a local address still lingering in TIME_WAIT, so a restarted server can re-listen on the same port immediately; call it before bind().
SO_REUSEADDR trades TIME_WAIT protection for restartability: by skipping the kernel's cooldown, delayed segments from a previous connection on the same address can in principle reach the new socket.
fd | the socket. |
0 on success, -1 on error.
O(1).
none.
CheatahSocket.ListenLowLevelSocketCompileRun.SetReuseaddrStdlibE2E.SocketBind fd to host: port.
Resolves host via getaddrinfo and assigns the resulting local address to the socket; a resolution failure returns -1 with errno set to EADDRNOTAVAIL (see the ResolveFailure test).
fd | the socket. |
host | interface to bind. |
port | TCP port (0 = OS-assigned). |
0 on success, -1 on error.
O(1) + resolution.
none (the resolver's transient getaddrinfo list is freed before returning).
SocketCompileRun.BindStdlibE2E.SocketMark fd as a passive (listening) socket.
Switches an already-bound socket into the listening state so accept() can pull connections from it; backlog caps how many fully-established connections may queue before new ones are refused.
fd | the socket. |
backlog | queue length. |
0 on success, -1 on error.
O(1).
none.
CheatahSocket.ListenLowLevelSocketCompileRun.ListenStdlibE2E.SocketConnect fd to host: port.
Resolves host and blocks until the TCP handshake succeeds or fails; a refused connection returns -1 with errno ECONNREFUSED (see the ConnectRefused test). Unlike tcp_connect() it does not close the fd on failure — the caller still owns fd.
fd | the socket. |
host | destination. |
port | destination port. |
0 on success, -1 on error.
O(1) + DNS.
none (the resolver's transient getaddrinfo list is freed before returning).
blocks until the TCP handshake completes or fails.
CheatahSocket.ConnectRefusedSocketCompileRun.ConnectStdlibE2E.SocketAccept one pending connection.
Blocks until a client connects, then returns a new fd for that one connection (the listening fd stays open for further accepts). The returned client fd is owned by the caller and must be closed separately; the peer address is discarded.
fd | a listening fd. |
the connected client fd, or -1 on error.
O(1) syscall (blocks until a client arrives).
none.
blocks the calling thread until a client connects.
CheatahSocket.LoopbackSocketCompileRun.AcceptStdlibE2E.Socket SystemApps.NetworkRoundtripThe local TCP port fd is bound to (useful after binding to port 0).
Reads the address actually assigned via getsockname and returns its port in host byte order; this is the way to discover the ephemeral port the OS chose when you bound to port 0.
fd | a bound socket. |
the port, or -1 on error.
O(1) syscall.
none.
CheatahSocket.LoopbackSocketCompileRun.LocalPortStdlibE2E.Socket SystemApps.NetworkRoundtripSend some of data (one send).
Issues a single send, which may transmit fewer bytes than supplied (a partial send); the caller is responsible for re-sending the remainder, or use sendall() to loop automatically.
fd | a connected fd. |
data | bytes to send. |
bytes actually sent, or -1 on error.
O(n).
none (MSG_NOSIGNAL, so a broken pipe never raises SIGPIPE).
CheatahSocket.SendallSocketCompileRun.SendStdlibE2E.SocketSend data in full, looping until all bytes are written.
Repeatedly calls send on the unsent remainder until every byte is written, so unlike send() there are no partial sends to handle; it aborts with -1 the moment a send returns <= 0 (error or peer hang-up), in which case some bytes may already have been transmitted.
fd | a connected fd. |
data | bytes to send. |
0 on success, -1 on error.
O(n).
none.
may block while the peer's receive window is full; bounded per send by the set_timeout() send deadline.
CheatahSocket.SendallSocketCompileRun.SendallStdlibE2E.Socket SystemApps.NetworkRoundtripReceive up to bufsize bytes.
Blocks for one recv and returns whatever bytes arrive (possibly fewer than bufsize); the result is binary-safe, so a returned string may contain embedded NULs and its length is the true byte count. A clean EOF (peer closed) and an error both yield "", so check last_error() to tell them apart; bufsize <= 0 also returns "" without touching the socket.
fd | a connected fd. |
bufsize | maximum bytes to read. |
the bytes read (binary-safe), or "" on EOF/error.
O(bufsize).
allocates the returned string (and grows a reused per-thread scratch buffer up to bufsize on first use).
blocks until data, EOF, or the set_timeout() deadline; a shutdown() from another thread wakes it with EOF.
CheatahSocket.LoopbackSocketCompileRun.RecvStdlibE2E.Socket SystemApps.NetworkRoundtripClose a socket.
Releases the fd back to the OS; after this the fd is invalid and must not be reused. Closing an already-closed or never-opened fd fails with -1 (EBADF), which is how the BadFd test exercises the error path.
fd | the fd to close. |
0 on success, -1 on error.
O(1) syscall.
none.
CheatahSocket.BadFdSocketCompileRun.CloseStdlibE2E.Socket SystemApps.NetworkRoundtripHalf-close fd in both directions (::shutdown SHUT_RDWR) WITHOUT releasing it.
A blocking recv() on another thread returns immediately (EOF) — the safe way to wake a reader for a clean shutdown. The fd is still owned by the caller and must be close()d afterwards.
fd | the fd to half-close. |
0 on success, -1 on error.
O(1) syscall.
none.
safe to call from another thread while a recv() on fd blocks — waking that reader is exactly what it is for.
CheatahSocket.TimeoutThenShutdownCreate a TCP socket bound to host: put it in the listening state (sets port andSO_REUSEADDR).
Performs socket()/set_reuseaddr/bind/listen in one shot; on any failure it closes the partially-created socket and returns -1, so the caller never leaks an fd. On success the returned fd is owned by the caller and must be passed to close() when done.
host | interface to bind ("127.0.0.1", "0.0.0.0", …). |
port | TCP port (0 = let the OS pick — read it back with local_port()). |
backlog | pending-connection queue length. |
the listening fd, or -1 on error.
O(1) + resolution (a few syscalls).
none (the resolver's transient getaddrinfo list is freed before returning).
CheatahSocket.LoopbackSocketCompileRun.TcpListenStdlibE2E.Socket SystemApps.NetworkRoundtripCreate a TCP socket and connect it to host: port.
The host is resolved via getaddrinfo, so names, "localhost", and dotted IPs all work; the connect blocks until the handshake completes or fails. On failure the socket is closed and -1 is returned; on success the caller owns the connected fd and must close() it.
host | destination host (name or IP). |
port | destination port. |
the connected fd, or -1 on error.
O(1) + DNS resolution.
none (the resolver's transient getaddrinfo list is freed before returning).
blocks until the TCP handshake completes or fails.
CheatahSocket.LoopbackSocketCompileRun.TcpConnectStdlibE2E.Socket SystemApps.NetworkRoundtripA UDP socket — the DATAGRAM face beside the stream one.
Unbound until bind; a client that only sends needs no bind (the kernel picks a port on the first sendto).
What a datagram is for: data whose NEXT packet supersedes this one — a presence pose, a live drag, a simulation snapshot. It may be dropped, duplicated or reordered by the network and the receiver must be written for that (newest-wins by stamp); nothing here acks, retries or orders. Everything that must arrive rides TCP (tcp_connect).
the socket fd, or -1 (last_error says why).
O(1).
none.
CheatahSocket.UdpLoopbackSocketCompileRun.UdpLoopbackStdlibE2E.Socketlong long sendto(long long fd, const std::string &host, long long port, const std::string &data)
source#
Send one datagram to host:(an IPv4 literal or a name; resolved per call, so cache the address yourself on a hot path). port
The whole of data is one packet: keep it under the path MTU (1200 bytes is safe on the public internet, 65507 the absolute cap).
fd | a socket from udp_socket. |
host | destination host. |
port | destination port. |
data | the packet. |
bytes sent (== data.size()), or -1.
O(len) + the kernel's copy.
none (the resolve is on the stack).
CheatahSocket.UdpLoopbackSocketCompileRun.UdpLoopbackStdlibE2E.Socketstd::string recvfrom(long long fd, long long bufsize, std::string &out_host, long long &out_port)
source#
Receive one datagram: at most bufsize bytes of it (the rest of a larger packet is DISCARDED — the datagram contract), with the sender's address in out_host / out_port.
Blocks until a packet arrives, or until set_timeout's window passes (an empty string, out_port 0).
fd | a socket from udp_socket, bound with bind. |
bufsize | the most bytes to take. |
out_host | the sender's address, dotted (empty on timeout/error). |
out_port | the sender's port (0 on timeout/error). |
the packet's bytes, or empty.
O(bufsize) worst case.
the returned string (the receive buffer is a reused per-thread scratch).
CheatahSocket.UdpLoopbackSocketCompileRun.UdpLoopbackStdlibE2E.SocketBound both blocking directions of fd by timeout_ms (SO_RCVTIMEO + SO_SNDTIMEO), so a silent peer cannot hang a recv/send forever.
A recv that times out returns "" (check last_error() to distinguish from EOF). timeout_ms <= 0 clears the timeouts (block forever).
fd | a socket. |
timeout_ms | the per-operation bound in milliseconds. |
0 on success, -1 on error.
O(1) (two setsockopt calls).
none.
CheatahSocket.TimeoutThenShutdownThe message for the current errno.
Returns the human-readable text for the thread's current errno; call it right after a function reports failure (a -1 return, or "" from recv), since any later syscall may overwrite errno.
strerror(errno).
O(1).
allocates the returned string.
CheatahSocket.ConnectRefusedSocketCompileRun.LastErrorStdlibE2E.SocketOpen a client TCP connection to host: return it as an owning Conn (the RAII, port andwith-friendly form of tcp_connect()).
host | destination host (name or IP). |
port | destination port. |
an owning Conn; on failure its is_open() is false (see last_error()).
O(1) + DNS resolution.
none beyond the Conn itself.
blocks until the TCP handshake completes or fails.
CheatahSocket.ConnLoopbackCreate a listening server socket bound to host: return it as an owning Listener (the RAII, port andwith-friendly form of tcp_listen()).
host | interface to bind ("127.0.0.1", "0.0.0.0", …). |
port | TCP port (0 = let the OS pick — read it back with Listener::local_port()). |
backlog | pending-connection queue length. |
an owning Listener; on failure its is_open() is false (see last_error()).
O(1) + resolution (a few syscalls).
none beyond the Listener itself.
CheatahSocket.ListenerLoopback