std/network/udp
std/network/src/udp.trb
UDP: a UdpSocket sends and receives datagrams - each one whole, with the address it came from, or not at all
(docs/design/NETWORK.md section 4, slice 5). A datagram is not a stream, so a socket is no Source: a receive answers
one datagram and its sender, and a send hands one datagram to the operating system.
A socket is a handle of the runtime, like a TCP one, and is closed exactly once, by the close() the release of its
owner runs.
type UdpSocket
shared type UdpSocket with Close
A UDP socket: bound to a local address, and - once UdpSocket.connect named one - connected to one peer. 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 socket = UdpSocket.bind(SocketAddress(IpAddress.loopback, 0))?
socket.send("ping".bytes().toList(), to: server).await()?
const (answer, sender) = socket.receive().await()?
Nothing is promised of a datagram on its way: it may be lost, arrive twice or overtake another, and a protocol over
UDP that needs more (DNS, QUIC) asks again after a timeout - receive().within(limit). What does arrive arrives
whole, up to the largest datagram there is (65,507 bytes over IPv4).
fn bind
static fn bind(address: SocketAddress): Result<UdpSocket, NetworkError>
A socket bound to address. Port 0 asks the system for a free port, which UdpSocket.localAddress then says; an
IPv6 address binds IPv6 only, on every system.
Errors
NetworkErrorthatisAddressInUse()where another socket has the address.
fn localAddress
fn localAddress(): SocketAddress
Where it is bound, with the port the system chose where port 0 was asked for.
fn connect
fn connect(address: SocketAddress): Result<Void, NetworkError>
Connects the socket to one peer, which waits for nothing - no datagram goes over the network. From now on only the
peer's datagrams arrive, UdpSocket.sendToPeer sends to it, and a peer whose port answers "unreachable" makes the
next receive fail with isConnectionRefused(). Connecting again names another peer.
Errors
NetworkErrorfor an address of the other IP version than the socket's, or port 0.
fn peerAddress
fn peerAddress(): SocketAddress?
The peer UdpSocket.connect named, or None for a socket that is not connected.
fn send
fn send(bytes: Bytes, to: SocketAddress): Task<Result<Void, NetworkError>>
Sends bytes as one datagram to to. Finishes once the operating system took it, which says nothing of whether it
arrives. A connected socket sends to its peer only.
Errors
NetworkErrorfor a datagram larger than the network carries, an address of the other IP version, or an address that is not the peer of a connected socket.
fn sendToPeer
fn sendToPeer(bytes: Bytes): Task<Result<Void, NetworkError>>
Sends bytes as one datagram to the peer UdpSocket.connect named.
Errors
NetworkErrorfor a socket that is not connected, and for a datagram larger than the network carries.
fn receive
fn receive(): Task<Result<(Bytes, SocketAddress), NetworkError>>
The next datagram and where it came from. Waits until one arrives; a datagram that arrives while nobody receives
waits in the socket, and a cancelled receive leaves it to the next one. A timeout is within:
socket.receive().within(2.seconds()).await().
Errors
NetworkErrorthatisConnectionRefused()on a connected socket whose peer's port is unreachable, andisClosed()once the socket was closed.
fn close
var fn close()
Closes the socket: a receive that waits fails with a closed socket. What the release of the socket runs.