A general purpose .. programming language written in zig ijadux2.tngl.sh/Rinnescript
zig language
2.3 kB

net — TCP client/server builtins #

Blocking, cross-platform TCP over the runtime's Io engine.

Listening #

@import = .{ net, std };
const l = net.tcp_listen(0);      // port 0 = ephemeral; pick with l.port()
std.print("listening on {}\n", .{l.port()});
Listener method Effect
l.port() bound port (resolves ephemeral port 0)
l.accept() block until a client arrives → stream
l.close() stop listening

Connecting #

@import = .{ net, std };
const c = net.tcp_connect("127.0.0.1", 8080);

Streams #

Stream method Effect
s.read(max) up to max bytes as a string; returns early at EOF, otherwise waits for bytes
s.write(data) send a string (flushed before returning); returns length
s.shutdown(how) half-close; how = "send", "recv", "both" (default "send")
s.close() close the socket

Message framing: on blocking platforms read(max) cannot know where your message ends. Half-close the sender (c.shutdown()) after writing a complete message — the peer's read then returns immediately at EOF while the reverse direction stays open for the reply.

Errors surface as runtime errors: cannot listen / cannot resolve host / cannot connect / accept failed / read or write failed.

Runnable example (both roles in one script) #

@import = .{ net, std };

pub fn main() int {
    const l = net.tcp_listen(0);
    const p = l.port();
    std.print("listening on 127.0.0.1:{}\n", .{p});

    const c = net.tcp_connect("127.0.0.1", p);
    c.write("ping");
    c.shutdown();

    const s = l.accept();
    const got = s.read(64);
    std.print("server got: {}\n", .{got});

    s.write("pong");
    s.shutdown();
    const back = c.read(64);
    std.print("client got: {}\n", .{back});

    c.close();
    s.close();
    l.close();
    return 0;
}

More examples #

See examples/net_demo.rg — dual-role TCP loopback echo with half-close framing.