std/network/tcp
std/network/src/tcp.trb
TCP: TcpListener accepts connections, TcpStream is one, and resolve turns a name into addresses. Everything that
waits for the network answers a Task, and a connection's two directions are a Source and a Sink of Bytes
(docs/design/NETWORK.md sections 2 and 4).
A socket is a handle of the runtime, an Int: the types here are TorbScript over the natives of runtime/io.c, and
a handle is closed exactly once, by the close() the release of its owner runs.
fn resolve
fn resolve(host: String): Task<Result<List<IpAddress>, NetworkError>>
The addresses host names: a literal address as it is, localhost as the two loopback addresses, and every other
name through the system's resolver, in the order it answered.
const addresses = resolve("localhost").await()?
Errors
NetworkErrorthatisHostNotFound()where the name resolves to nothing.
type TcpListener
shared type TcpListener with Close
A socket that listens for connections. It has an identity - the operating system's socket - so it is a shared type, and it closes when the last reference to it goes.
using listener = TcpListener.listen(SocketAddress(IpAddress.loopback, 0))?
var connection = listener.accept().await()?
Related
TcpStream- whatacceptanswers.
fn listen
static fn listen(address: SocketAddress, backlog: Int = 128): Result<TcpListener, NetworkError>
Listens on address. Port 0 asks the system for a free port, which TcpListener.localAddress then says. An IPv6
address listens for IPv6 only, on every system.
Errors
NetworkErrorthatisAddressInUse()where another socket has the address.
fn localAddress
fn localAddress(): SocketAddress
Where it listens, with the port the system chose where port 0 was asked for.
fn accept
fn accept(): Task<Result<TcpStream, NetworkError>>
The next connection. Waits until one arrives; a cancelled accept leaves the connection to the next one.
fn acceptor
fn acceptor(): TcpAcceptor
A value that accepts connections on this listener from any task, on any worker: several accept loops on one listening socket, which is how a server serves on every core (docs/design/NETWORK.md section 4). It holds the socket's handle and nothing else, so it moves to another worker with the task that holds it; it does not own the socket, which the listener closes - and then every accept of every acceptor fails with a closed socket.
fn stop
fn stop()
Stops listening before the listener is released: an accept that waits fails with a closed socket, and so does
every later one. Stopping twice is nothing. A server that shuts down gracefully calls it; the release of the
listener does the same by itself.
fn close
var fn close()
Stops listening, as TcpListener.stop does: what the release of the listener runs.
type TcpAcceptor
type TcpAcceptor
What TcpListener.acceptor answers: the right to accept on a listening socket, as a value that moves between workers.
Several acceptors of one listener accept at once, each connection going to exactly one of them. It is the handle and
nothing else - no address, no text - because a task moves to an idle worker only where its frame holds plain values
of at most 32 bytes each (docs/design/CONCURRENCY.md section 16, "What crosses a worker").
fn accept
fn accept(): Task<Result<TcpStream, NetworkError>>
The next connection, on the worker of the task that asked. Waits until one arrives.
Errors
NetworkErrorthatisClosed()once the listener stopped listening or was released.
type TcpStream
shared type TcpStream with Close
One TCP connection: bytes in both directions, in order, until either side ends its half. A shared type, because it
is the operating system's socket; it closes when the last reference to it - the stream, its source or its sink - goes.
using stream = TcpStream.connectTo("localhost", 8080).await()?
var writing = stream.sink()
writing.addText("ping").await()?
Related
fn of
static fn of(handle: Int): TcpStream
A stream over a handle the runtime answered.
fn connect
static fn connect(address: SocketAddress): Task<Result<TcpStream, NetworkError>>
A connection to address.
Errors
NetworkErrorthatisConnectionRefused()where nothing listens there.
fn connectTo
static fn connectTo(host: String, port: Int): Task<Result<TcpStream, NetworkError>>
A connection to port of host: the host is resolved, and each of its addresses is tried in turn until one
connects. The failure of the last one is the failure.
fn localAddress
fn localAddress(): Result<SocketAddress, NetworkError>
The address of this end.
fn remoteAddress
fn remoteAddress(): Result<SocketAddress, NetworkError>
The address of the other end.
fn receive
fn receive(maximum: Int = 65536): Task<Result<Bytes?, NetworkError>>
At most maximum bytes, as soon as any arrived: Some(bytes), or None once the peer ended its half. One receive at
a time; bytes that arrive while nobody receives wait in the operating system.
fn receiveBuffer
fn receiveBuffer(maximum: Int = 65536): Task<Result<ArrayList<UInt8>?, NetworkError>>
TcpStream.receive as the ArrayList the bytes arrive in, which a reader that buffers appends without a copy.
fn send
fn send(bytes: Bytes): Task<Result<Void, NetworkError>>
Writes all of bytes; finishes once the operating system took them, which is when a full peer has read.
fn sendBuffer
fn sendBuffer(bytes: ArrayList<UInt8>): Task<Result<Void, NetworkError>>
TcpStream.send for bytes that are an ArrayList already, which is copied once instead of twice.
fn shutdown
fn shutdown(): Result<Void, NetworkError>
Ends this half: the peer reads the end of the stream, and may still answer.
fn source
fn source(chunk: Int = 65536): TcpSource
The reading direction as a Source: at most chunk bytes per next(), and None once the peer ended.
fn sink
fn sink(): TcpSink
The writing direction as a Sink: end() ends this half, close() does nothing of its own.
fn close
var fn close()
Closes the socket. What waits on it fails; the peer reads the end of the stream, or a reset.
type TcpSource
shared type TcpSource with Source<Bytes, NetworkError>
The reading direction of a TcpStream: a Source<Bytes, NetworkError>.
fn of
static fn of(stream: TcpStream, chunk: Int): TcpSource
The source of stream: what TcpStream.source answers.
fn next
var fn next(): Task<Result<Bytes?, NetworkError>>
Not documented.
fn close
var fn close()
Nothing of its own: the stream closes once its last holder is gone.
type TcpSink
shared type TcpSink with Sink<Bytes, NetworkError>
The writing direction of a TcpStream: a Sink<Bytes, NetworkError>.
fn of
static fn of(stream: TcpStream): TcpSink
The sink of stream: what TcpStream.sink answers.
fn add
var fn add(item: Bytes): Task<Result<Void, NetworkError>>
Not documented.
fn end
var fn end(): Task<Result<Void, NetworkError>>
Ends this half of the connection: the peer reads the end of the stream.
fn close
var fn close()
Nothing of its own: the stream closes once its last holder is gone.