Skip to content
Kavachकवच

Sockets: TCP

● Intermediate2 min

TCP is a connection: bytes arrive complete and in order. net.listen and accept on one side, net.connect on the other.

use std.net

fn echo_once(listener: Listener) ! NetError uses Net {
    const conn = try listener.accept()
    while true {
        const data = (try conn.read()) ?? break
        try conn.write(data)
    }
}

fn main() ! Error {
    const listener = try net.listen("127.0.0.1:0")
    const _server = spawn echo_once(listener)
    const conn = try net.connect(listener.address())
    try conn.write("namaste".bytes())
    const back = (try conn.read()) ?? Bytes([])
    print(back.text() ?? "?")
    conn.close()
}

The program ran and printed:

kavach run echo.kav

namaste
echo.kav: Kavach code, then what running it prints

TCP carries a stream of bytes, not messages: a protocol on top of it, as HTTP is, says where one message ends.

Closed when let go

conn.close() closes a connection, and so does letting it go: when its last holder's block ends, it is closed, as a value with Drop is. So a connection a function opens and doesn't return is closed when the function ends, and the other side reads the end:

use std.net

fn serve(listener: Listener) -> String ! NetError uses Net {
    const conn = try listener.accept()
    let got = ""
    while true {
        if let piece = try conn.read() {
            got = got + (piece.text() ?? "?")
        } else {
            return "got {got}, then the end"
        }
    }
    got
}

/// Opens a connection and writes to it, but never closes it.
fn send(address: String) ! NetError uses Net {
    const conn = try net.connect(address)
    try conn.write("hello".bytes())
}

fn main() ! Error {
    const listener = try net.listen("127.0.0.1:0")
    const server = spawn serve(listener)
    try send(listener.address())
    print(try server.wait().timeout(5.seconds))
}

The program ran and printed:

kavach run close-holder.kav

got hello, then the end
close-holder.kav: Kavach code, then what running it prints

A listener is closed the same way, and so is an HTTP/2 client.

tested