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
namasteTCP 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 endA listener is closed the same way, and so is an HTTP/2 client.
tested