TcpStream

public struct TcpStream { /* private fields */ }

A connected TCP byte stream — implements Readable and Writable on top of a POSIX socket fd.

Returned by TcpListener.accept() (server side) and TcpStream.connect(host:port:) (client side). Reads and writes go directly through recv(2) / send(2); partial reads/writes are surfaced — the caller is responsible for looping. The owned fd is closed automatically by the deinit unless detachFd has been called first.

Examples

var stream = match TcpStream.connect("example.com", 80) { .Ok(s) => s, .Err(e) => return .Err(e) }; // stream is Readable + Writable

Representation

A single RcBox[Int32] holding the file descriptor; -1 means "detached, do not close on drop".

Memory Model

Reference-counted shared ownership of the fd. Cloning is a refcount bump (the same socket), and close(2) runs exactly once — when the last handle drops. This is a shared handle, not a dup(2); use dup(2) explicitly if you need an independent fd.

Initializers

public init(Int32)

Wraps an existing socket fd as a TcpStream.

The stream takes ownership; the deinit will close the fd. Callers obtaining the fd from accept / socket should hand it over and stop using it directly.

Methods

public static func connect(String, UInt16) -> Result[TcpStream, IoError]

Resolves host:port and returns a connected TcpStream.

Uses getaddrinfo for resolution and tries the first result. Constrained to IPv4 / TCP via the hints block. On any failure the partially-built fd is closed and the resolver list is freed before returning. Does not currently fall through to the next addrinfo entry on a failed connect — try one address.

Errors

  • Returns Err(IoError(code: eai)) with the EAI_* resolver code if getaddrinfo fails (note: this is a libc resolver code, not an errno).
  • Returns Err(IoError.last()) from errno if socket() or connect() fail.

Examples

match TcpStream.connect("example.com", 80) { .Ok(stream) => /* use stream */ {}, .Err(e) => print(e.message) }
public mutating func detachFd() -> Int32

Releases ownership of the fd and returns it.

Stores the -1 sentinel so the deinit becomes a no-op for every handle sharing this socket. The caller takes responsibility for closing the returned fd. Use this when handing the fd to another owner (e.g. an event loop, a child process, or a TLS stream).

public func rawFd() -> Int32

Returns the underlying fd without giving up ownership.

Useful for passing the fd to syscalls that the wrapper does not expose (fcntl, setsockopt, …). Do not close it yourself — the deinit still will.

ImplementsReadable

Methods

public mutating func read(into: ArraySlice[UInt8]) -> Result[Int64, IoError]

Reads up to buf.count bytes into buf. Returns the byte count actually read.

0 indicates the peer closed the connection cleanly. Required by the Readable protocol.

Errors

Returns Err(IoError) from the captured errno if recv returns -1.

ImplementsWritable

Methods

public mutating func flush() -> Result[(), IoError]

No-op — TCP sockets do not have an application-level write buffer.

Always returns Ok(()). Provided to satisfy the Writable protocol so generic writers can call flush unconditionally.

public mutating func write(from: ArraySlice[UInt8]) -> Result[Int64, IoError]

Writes up to buf.count bytes from buf. Returns the byte count actually written.

May write fewer bytes than requested under back-pressure; loop until the buffer is drained. Required by the Writable protocol.

Errors

Returns Err(IoError) from the captured errno if send returns -1.

ImplementsCloneable

Methods

public func clone() -> TcpStream

Defined in lang/std/net/socket.ks