Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Development · Evolving reference

TcpStream

Owns one nonblocking TCP byte stream implementing structural Reader/Writer. Reads/writes may transfer a short prefix or return WouldBlock; no implicit wait, thread or loop is introduced. Mutable loans serialize operations and close; cross-thread sharing requires external synchronization. Move transfers close authority and leaves the source closed. Destruction closes once without flush; explicit Close reports errors and consumes authority even on native failure. Flush has no userspace cache to drain and never promises peer receipt/durability.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. Read the status →

Module std.net

import std.net;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

TcpStream

pub final class TcpStream

Owns one nonblocking TCP byte stream implementing structural Reader/Writer. Reads/writes may transfer a short prefix or return WouldBlock; no implicit wait, thread or loop is introduced. Mutable loans serialize operations and close; cross-thread sharing requires external synchronization. Move transfers close authority and leaves the source closed. Destruction closes once without flush; explicit Close reports errors and consumes authority even on native failure. Flush has no userspace cache to drain and never promises peer receipt/durability.

Example

module example.tcp_socket;
from std.net import TcpStream, TcpListener, Address, Endpoint;
from std.io import WriteAll, ReadExactly;
fn Main() -> i32 {
    var Closed = TcpStream();
    let Input: byte[1] = [0xA1_byte];
    switch WriteAll(Closed, Input) {
        case .Err { Error = PatternPayload5085 } => {
            switch PatternPayload5085 {
                case .Failure { Reason = PatternPayload5086, Transferred = Count } => {
                    switch PatternPayload5086 {
                        case .Network { Reason = PatternPayload5087 } if (PatternPayload5087 is .Closed) => { if Count != 0 { return 1; } }
                        default => return 2;
                    }
                }
                default => return 2;
            }
        }
        default => return 2;
    }
    var Output: byte[1] = [0xB2_byte];
    switch Closed.Read(Output) {
        case .Err { Error = PatternPayload5088 } => {
            switch PatternPayload5088 {
                case .Failure { Reason = PatternPayload5089 } => {
                    switch PatternPayload5089 {
                        case .Network { Reason = PatternPayload5090 } if (PatternPayload5090 is .Closed) => {}
                        default => return 3;
                    }
                }
                default => return 3;
            }
        }
        default => return 3;
    }
    if Output[0] != 0xB2_byte { return 4; }
    switch ReadExactly(Closed, Output) {
        case .Err { Error = PatternPayload5091 } => {
            switch PatternPayload5091 {
                case .Failure { Reason = PatternPayload5092, Transferred = Count } => {
                    switch PatternPayload5092 {
                        case .Network { Reason = PatternPayload5093 } if (PatternPayload5093 is .Closed) => { if Count != 0 || Output[0] != 0xB2_byte { return 20; } }
                        default => return 21;
                    }
                }
                default => return 21;
            }
        }
        default => return 21;
    }
    switch Closed.Flush() {
        case .Err { Error = PatternPayload5094 } => {
            switch PatternPayload5094 {
                case .Failure { Reason = PatternPayload5095 } => {
                    switch PatternPayload5095 {
                        case .Network { Reason = PatternPayload5096 } if (PatternPayload5096 is .Closed) => {}
                        default => return 5;
                    }
                }
                default => return 5;
            }
        }
        default => return 5;
    }
    switch Closed.ShutdownWrite() {
        case .Err { Error = PatternPayload5097 } => {
            switch PatternPayload5097 {
                case .Failure { Reason = PatternPayload5098 } if (PatternPayload5098 is .Closed) => {}
                default => return 6;
            }
        }
        default => return 6;
    }
    switch Closed.ReadLocalEndpoint() {
        case .Err { Error = PatternPayload5099 } => {
            switch PatternPayload5099 {
                case .Failure { Reason = PatternPayload5100 } if (PatternPayload5100 is .Closed) => {}
                default => return 7;
            }
        }
        default => return 7;
    }
    switch Closed.ReadPeerEndpoint() {
        case .Err { Error = PatternPayload5101 } => {
            switch PatternPayload5101 {
                case .Failure { Reason = PatternPayload5102 } if (PatternPayload5102 is .Closed) => {}
                default => return 8;
            }
        }
        default => return 8;
    }
    if Closed.Close() is .Err { Error = _ } { return 9; }
    let Local = Endpoint.Create(Address.CreateIPv4(127_byte, 0_byte, 0_byte, 1_byte), 0_u16);
    var Listener = {
        // Scoped writable carriers end immediately after explicit payload transfer.
        var ListenerCreation = TcpListener.TryListen(Local, 8);
        switch ListenerCreation {
            case .Ok { Value = Value: mut TcpListener& } => break move(Value);
            case .Err => return 10;
        }
    };
    let Bound = switch Listener.ReadLocalEndpoint() { case .Ok { Value = Value } => break Value; case .Err => return 11; };
    if Bound.Port == 0 || !Bound.Address.IsLoopback { return 12; }
    var Moved = move(Listener);
    if !Listener.IsClosed || Moved.IsClosed { return 13; }
    // Keep the accepted stream in writable result storage until transfer.
    var Acceptance = Moved.TryAccept();
    switch Acceptance {
        case .Err { Error = PatternPayload5103 } => {
            switch PatternPayload5103 {
                case .Failure { Reason = PatternPayload5104 } if (PatternPayload5104 is .WouldBlock) => {}
                default => return 17;
            }
        }
        case .Ok { Value = Stream: mut TcpStream& } => {
            var Accepted = move(Stream);
            if Accepted.IsClosed { return 14; }
            var Transferred = move(Accepted);
            if !Accepted.IsClosed || Transferred.IsClosed { return 15; }
            if Transferred.Close() is .Err { Error = _ } { return 16; }
        }
    }
    if Moved.Close() is .Err { Error = _ } { return 18; }
    if !Moved.IsClosed || Moved.Close() is .Err { Error = _ } { return 19; }
    return 0;
}

TcpStream.init

pub init()

Creates a closed owner without native effects.

TcpStream.init

pub init(Source: readonly Self&) = delete;

Rejects duplicated close authority. Source: Existing owner.

TcpStream.init

pub init(Source: mut Self&&)

Transfers authority without native I/O, leaving source closed. Source: Writable source consumed by movement.

TcpStream.operator

pub fn operator =(Source: readonly Self&) -> void = delete;

Rejects copying ownership. Source: Existing owner. Return: No runtime result; this assignment is deleted and cannot be invoked.

TcpStream.operator

pub fn operator =(Source: mut Self&&) -> void = delete;

Requires explicit close before replacement. Source: Existing owner. Return: No runtime result; this assignment is deleted and cannot be invoked.

TcpStream.IsClosed

pub IsClosed: bool;

Observes closed/moved state without native calls. Return: True when no close authority remains.

TcpStream.ConnectAsync

pub static async fn ConnectAsync(mut Remote: Endpoint, Token: CancellationToken) -> Task<Result<Self, NetworkError>>

Connects a numeric peer without blocking a worker or resolving a name. Remote: Copied numeric endpoint with nonzero port. Token: Owned cancellation observation, inert by default. Return: Sole connected stream or typed error; failed/cancelled acquisition closes. Warning: May lazily start the shared reactor; local close authority remains retained across every suspension. No connection timeout is implied.

Example

module example.async_socket;
from std.net import TcpStream, TcpListener, UdpSocket, Address, Endpoint;
from std.io import ReadExactlyAsync, WriteAllAsync;
from std.task import Task, CancellationSource;
async fn Main() -> Task<i32> {
    let Local = Endpoint.Create(Address.CreateIPv4(127_byte, 0_byte, 0_byte, 1_byte), 0_u16);
    var Listener = {
        // Scoped writable carriers end immediately after explicit payload transfer.
        var ListenerCreation = TcpListener.TryListen(Local);
        switch ListenerCreation {
            case .Ok { Value = Value: mut TcpListener& } => break move(Value);
            case .Err => return 1;
        }
    };
    let Bound = switch Listener.ReadLocalEndpoint() { case .Ok { Value = Value } => break Value; case .Err => return 2; };
    var Stop = {
        var StopCreation = CancellationSource.TryCreate();
        switch StopCreation {
            case .Ok { Value = Value: mut CancellationSource& } => break move(Value);
            case .Err => return 23;
        }
    };
    var Accept = Listener.AcceptAsync(Stop.Token); // Retains listener until terminal await.
    var Client = {
        var ClientCreation = await TcpStream.ConnectAsync(Bound);
        switch ClientCreation {
            case .Ok { Value = Value: mut TcpStream& } => break move(Value);
            case .Err => { Stop.RequestCancellation(); let Cleanup = await move(Accept); return 3; }
        }
    };
    var Server = {
        var ServerCreation = await move(Accept);
        switch ServerCreation {
            case .Ok { Value = Value: mut TcpStream& } => break move(Value);
            case .Err => return 4;
        }
    };
    let Input: byte[2] = [0xA1_byte, 0xB2_byte];
    var Output: byte[2] = [0_byte, 0_byte];
    if await WriteAllAsync(Client, Input) is .Err { Error = _ } { return 5; }
    if await ReadExactlyAsync(Server, Output) is .Err { Error = _ } { return 6; }
    if Output[0] != Input[0] || Output[1] != Input[1] { return 7; }
    if await Client.FlushAsync() is .Err { Error = _ } { return 8; }
    if Client.ShutdownWrite() is .Err { Error = _ } { return 9; }
    switch await Server.ReadAsync(Output) { case .Ok { Value = Count } => { if Count != 0 { return 10; } } case .Err => return 11; }
    if Client.Close() is .Err { Error = _ } { return 12; }
    if Server.Close() is .Err { Error = _ } { return 13; }
    // Client has been closed after the original paired byte exchange.
    // This convenience call must refuse before native send/readiness work,
    // preserving peer bytes and proving zero progress on the closed owner.
    switch await Client.WriteAsync(Input) {
        case .Err { Error = ClosedError } => {
            switch ClosedError {
                case .Failure { Reason = Reason, Transferred = Count } => {
                    if Count != 0 { return 24; }
                    switch Reason {
                        case .Network { Reason = Network } if (Network is .Closed) => {}
                        default => return 24;
                    }
                }
                default => return 24;
            }
        }
        default => return 24;
    }
    if Listener.Close() is .Err { Error = _ } { return 14; }
    var Packet = {
        var PacketCreation = UdpSocket.TryBind(Local);
        switch PacketCreation {
            case .Ok { Value = Value: mut UdpSocket& } => break move(Value);
            case .Err => return 15;
        }
    };
    let Destination = switch Packet.ReadLocalEndpoint() { case .Ok { Value = Value } => break Value; case .Err => return 16; };
    switch await Packet.SendToAsync(Destination, Input) { case .Ok { Value = Count } => { if Count != 2 { return 17; } } case .Err => return 18; }
    switch await Packet.ReceiveFromAsync(Output) { case .Ok { Value = Receipt } => { if Receipt.Count != 2 || Receipt.IsTruncated || Receipt.Sender.Port != Destination.Port { return 19; } } case .Err => return 20; }
    if Output[0] != Input[0] || Output[1] != Input[1] { return 21; }
    if Packet.Close() is .Err { Error = _ } { return 22; }
    return 0;
}

TcpStream.ConnectAsync

pub static fn ConnectAsync(mut Remote: Endpoint) -> Task<Result<Self, NetworkError>>

Supplies the omitted arguments to ConnectAsync. Note: Defaults: Token = CancellationToken(). Remote: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

TcpStream.ConnectAsync

pub static async fn ConnectAsync(mut Remote: Endpoint, Limit: Deadline, Token: CancellationToken) -> Task<Result<Self, NetworkError>>

Connects against one unchanged absolute deadline. Limit: Finite compatible monotonic boundary or Endless; checked before attempts. Token: Owned cancellation observation, checked before deadline. Remote: Copied numeric peer with nonzero port. Return: Owned stream or typed cancellation/timeout/domain/native failure.

TcpStream.ConnectAsync

pub static fn ConnectAsync(mut Remote: Endpoint, Limit: Deadline) -> Task<Result<Self, NetworkError>>

Supplies the omitted arguments to ConnectAsync. Note: Defaults: Token = CancellationToken(). Remote: Same input, ownership and lifetime contract as the full operation. Limit: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

TcpStream.ReadAsync

pub async fn ReadAsync(Output: mut byte[], Token: CancellationToken) -> Task<Result<usize, IoError>>

Receives a bounded prefix, awaiting readiness only after WouldBlock. Output: Writable backing retained exclusively through terminal completion. Token: Owned cancellation observation. Return: Prefix count/EOF or typed IoError; no implicit exact-length read.

TcpStream.ReadAsync

pub fn ReadAsync(Output: mut byte[]) -> Task<Result<usize, IoError>>

Supplies the omitted arguments to ReadAsync. Note: Defaults: Token = CancellationToken(). Output: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

TcpStream.ReadAsync

pub async fn ReadAsync(Output: mut byte[], Limit: Deadline, Token: CancellationToken) -> Task<Result<usize, IoError>>

Performs one bounded transfer against an unchanged absolute deadline. Output: Exclusive initialized backing retained through completion. Limit: Finite compatible monotonic boundary or Endless; no retry resets it. Token: Owned cancellation observation checked before expiry. Return: Exact transfer/receipt or typed timeout/domain/cancellation/native failure.

TcpStream.ReadAsync

pub fn ReadAsync(Output: mut byte[], mut Limit: Deadline) -> Task<Result<usize, IoError>>

Supplies the omitted arguments to ReadAsync. Note: Defaults: Token = CancellationToken(). Output: Same input, ownership and lifetime contract as the full operation. Limit: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

TcpStream.WriteAsync

pub async fn WriteAsync(Input: readonly byte[], Token: CancellationToken) -> Task<Result<usize, IoError>>

Sends a bounded prefix without blocking a worker for readiness. Input: Readonly backing retained through terminal completion. Token: Owned cancellation observation. Return: Accepted prefix count or typed IoError; use WriteAllAsync for full transfer.

TcpStream.WriteAsync

pub fn WriteAsync(Input: readonly byte[]) -> Task<Result<usize, IoError>>

Supplies the omitted arguments to WriteAsync. Note: Defaults: Token = CancellationToken(). Input: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

TcpStream.WriteAsync

pub async fn WriteAsync(Input: readonly byte[], Limit: Deadline, Token: CancellationToken) -> Task<Result<usize, IoError>>

Performs one bounded transfer against an unchanged absolute deadline. Input: Readonly backing retained through completion. Limit: Finite compatible monotonic boundary or Endless; no retry resets it. Token: Owned cancellation observation checked before expiry. Return: Exact transfer/receipt or typed timeout/domain/cancellation/native failure.

TcpStream.WriteAsync

pub fn WriteAsync(Input: readonly byte[], mut Limit: Deadline) -> Task<Result<usize, IoError>>

Supplies the omitted arguments to WriteAsync. Note: Defaults: Token = CancellationToken(). Input: Same input, ownership and lifetime contract as the full operation. Limit: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

TcpStream.FlushAsync

pub async fn FlushAsync(Token: CancellationToken) -> Task<Result<void, IoError>>

Completes without waiting because this stream has no userspace cache. Token: Owned cancellation observation checked before completion. Return: Ok, cancelled or closed; no peer acknowledgment/durability promise.

TcpStream.FlushAsync

pub fn FlushAsync() -> Task<Result<void, IoError>>

Supplies the omitted arguments to FlushAsync. Note: Defaults: Token = CancellationToken(). Return: Exact full-operation result; no additional async frame is created.

TcpStream.FlushAsync

pub async fn FlushAsync(Limit: Deadline, Token: CancellationToken) -> Task<Result<void, IoError>>

Checks cancellation/deadline then completes this cache-free flush. Limit: Finite monotonic boundary or Endless; checked before flush. Token: Owned cancellation observation. Return: Ok or typed cancellation/timeout/domain/closed error; no peer acknowledgment.

TcpStream.FlushAsync

pub fn FlushAsync(mut Limit: Deadline) -> Task<Result<void, IoError>>

Supplies the omitted arguments to FlushAsync. Note: Defaults: Token = CancellationToken(). Limit: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

TcpStream.Read

pub fn Read(Output: mut byte[]) -> Result<usize, IoError>

Attempts one bounded receive without waiting for readiness. Output: Exclusive initialized destination retained through return. Return: Copied prefix count or typed network IoError. Zero with positive capacity means EOF; empty destination provides no EOF evidence.

TcpStream.Write

pub fn Write(Input: readonly byte[]) -> Result<usize, IoError>

Attempts one bounded send, preserving partial acceptance. Input: Borrowed bytes retained only through return. Return: Accepted prefix count or typed network IoError; use WriteAll for complete transfer policy. No hidden retry or readiness wait occurs.

TcpStream.Flush

pub fn Flush() -> Result<void, IoError>

Completes immediately because this owner has no userspace output cache. Return: Ok for an owned socket or typed Closed error. Accepted kernel data is not guaranteed delivered, acknowledged or durable.

TcpStream.ReadLocalEndpoint

pub fn ReadLocalEndpoint() -> Result<Endpoint, NetworkError>

Copies numeric local socket endpoint without name resolution. Return: Independent endpoint or typed native/closed failure.

TcpStream.ReadPeerEndpoint

pub fn ReadPeerEndpoint() -> Result<Endpoint, NetworkError>

Copies attached numeric peer endpoint without name resolution. Return: Independent endpoint or typed native/closed failure.

TcpStream.ShutdownWrite

pub fn ShutdownWrite() -> Result<void, NetworkError>

Ends TCP sending without releasing receive/close authority. Return: Native shutdown completion or typed failure; receive remains usable.

TcpStream.Close

pub fn Close() -> Result<void, NetworkError>

Consumes close authority once; already closed is immediate success. Return: Native completion/failure with authority retired on either outcome.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library