README

moonbitlang/async/socket does not have a README file

#
InvalidAddr

pub suberror InvalidAddr derive(ToJson,
Debug
)

impl Show for InvalidAddr

#
ResolveHostnameError

pub suberror ResolveHostnameError {
ResolveHostnameError(String)
} derive(ToJson,
Debug
)

Error message from failure in resolving a network hostname. The content of the error message is platfrom-dependent, so users should never depend on it.

#
Addr

type Addr derive(Compare, Eq, Hash)

impl Show for Addr

#
Addr::ip

fn Addr::ip(addr : Addr) -> UInt

#
Addr::is_ipv6

fn Addr::is_ipv6(addr : Addr) -> Bool

#
Addr::is_multicast

fn Addr::is_multicast(addr : Addr) -> Bool

#
Addr::new

fn Addr::new(ip : UInt, port : Int) -> Addr

#
Addr::parse

fn Addr::parse(src : String) -> Addr raise

Parse a string into IPv4 or IPv6 address, format should be ip:port for IPv4 or [ip]:port for IPv6

#
Addr::port

fn Addr::port(addr : Addr) -> Int

#
Addr::resolve

async fn Addr::resolve(host : String, port~ : Int, protocol? : IpProtocolPreference) -> Addr

Resolve a IPv4 or IPv6 address by hostname.

By default, Addr::resolve return the first available address. Preference on IPv4 v.s. IPv6 can be configured via protocol. See IPProtocolPreference for available options.

#
IpProtocolPreference

pub(all) enum IpProtocolPreference {
OnlyV4
OnlyV6
FavorV4
FavorV6
NoPreference
} derive(
Debug
)

#
Tcp

pub struct Tcp {
addr : Addr
// private fields
}

A Tcp connection
impl Reader for Tcp
impl Writer for Tcp

#
Tcp::addr

fn Tcp::addr(sock : Tcp) -> Addr

Get the local address of a TCP connection.

#
Tcp::close

fn Tcp::close(self : Tcp) -> Unit

#
Tcp::connect

async fn Tcp::connect(addr : Addr) -> Tcp

Make connection to a remote address using connect(2) system call.

#
Tcp::connect_to_host

async fn Tcp::connect_to_host(host : StringView, port~ : Int, protocol? : IpProtocolPreference) -> Tcp

Connect to a remote host using the happy eyeball algorithm. Preference on IPv4 v.s. IPv6 can be configured via protocol:

  • if protocol is NoPreference (the default behavior), the first successful connection will be returned, regardless of the protocol.
  • if protocol is FavorV4, an IPv6 connection will only be returned if no IPv4 address is available
  • if protocol is OnlyV4, connect_to_host will fail if no IPv4 address is available
  • if protocol is FavorV6, an IPv6 connection will only be returned if no IPv4 address is available
  • if protocol is OnlyV6, connect_to_host will fail if no IPv4 address is available

#
Tcp::enable_keepalive

fn Tcp::enable_keepalive(self : Tcp, idle_before_keep_alive? : Int, keep_alive_count? : Int, keep_alive_interval? : Int) -> Unit raise

Enable TCP keep alive on the socket.

idle_before_keep_alive is the duration of idle time in seconds to wait before sending the first keep alive probe.

keep_alive_count is the number of keep alive probe to try before closing the connection.

keep_alive_interval is the time in seconds between two keep alive probes.

#
Tcp::fd

fn Tcp::fd(self : Tcp) -> Int

#
TcpServer

pub struct TcpServer {
addr : Addr
// private fields
}

#
TcpServer::TcpServer

#alias(new, deprecated="`new` is deprecated, use `TcpServer` instead")
async fn TcpServer::TcpServer(addr : Addr, dual_stack? : Bool, reuse_addr? : Bool) -> TcpServer

Create a TCP server that is bound to addr, listening for incoming connections.

If addr is the IPv6 wildcard address [::] and dual_stack is true (true by default), the server will work in dual stack mode, accepting connections from both IPv4 clients and IPv6 clients. The address of IPv4 clients are represented via IPv4-mapped IPv6 address.

If addr is not [::], dual_stack is ignored.

If the port of addr is zero, the server will be bound to a random port, assigned by the operating system. The actual listen address can be retrieved via .addr().

If reuse_addr is true (false by default), the SO_REUSEADDR option will be enabled on the server, allowing binding to addr even if there are still dead-ish TIME_WAIT sockets on that address.

On Windows, TIME_WAIT sockets are always ignored, so the behavior is always reuse_addr=true and reuse_addr will be ignored.

On MacOS (BSD), reuse_addr has the extra side effect that a server binding to a specific address may "steal" the specific interface from a previous wildcard bind (0.0.0.0), and similarly a server binding to a wildcard address can bind to the remaining interfaces if a bind to a specific interface already exists. This side effect cannot be isolated, so reuse_addr should be used with this in mind.

#
TcpServer::accept

async fn TcpServer::accept(self : TcpServer) -> (Tcp, Addr)

Accept a new connection on a listening TCP server. The accepted connection will be returned together with the address of peer.

#
TcpServer::addr

#deprecated("use `.addr` instead")
fn TcpServer::addr(server : TcpServer) -> Addr

Get the address the server is listening on

#
TcpServer::close

fn TcpServer::close(self : TcpServer) -> Unit

#
TcpServer::fd

fn TcpServer::fd(self : TcpServer) -> Int

#
TcpServer::run_forever

async fn TcpServer::run_forever(self : TcpServer, f : async (Tcp, Addr) -> Unit, allow_failure? : Bool, max_connections? : Int) -> Unit

Start the main loop of a TCP server, keep listening for new connections and handle connections using the callback f. f will be supplied the new connection and the address of the client.

The client connection will be closed automatically after f exits, so f must not close the client connection. The server will be automatically closed if run_forever fails.

If allow_failure is true (true by default), failure in f will be silently ignored.

If max_connections is present, at most max_connections clients are allowed in parallel. New clients will only get handled after a previous client terminates.

#
UdpClient

pub struct UdpClient {
addr : Addr
// private fields
}

A UDP client "connected" to a remote UDP server.

UDP is a connectionless protocol, here "connected" means the client always send packet to and receive packet from the specified remote server.

UDP does not really have a clear client/server distinction, especially when multicast is involved. The essence of UdpClient is a UDP socket without a fixed/well-known port.

#
UdpClient::UdpClient

#alias(new, deprecated="`new` is deprecated, use `UdpClient` instead")
async fn UdpClient::UdpClient(addr : Addr) -> UdpClient

Create a new UDP client connected to server at addr. The client always send packet to and receive packet from the specified remote server.

If addr is a multicast address, connect will not be called under the hood, and the client may receive packets from arbitrary peer. However, since the port of the client is random, the client effectively can only receive packets from multicast servers that have received packets from this client.

#
UdpClient::addr

#deprecated("use `.addr` instead")
fn UdpClient::addr(self : UdpClient) -> Addr

Get the local address of a UDP client.

#
UdpClient::close

fn UdpClient::close(self : UdpClient) -> Unit

#
UdpClient::connect

fn UdpClient::connect(self : UdpClient, addr : Addr) -> Unit raise

Connect the client to a remote address, subsequently the client will send packets to this address, and only receive packets from this address.

Unicast UDP clients are connected automatically, so connect is mainly useful for turning a multicast client into a unicast one. The typical workflow is to create the client as a multicast client, send multicast packets, and wait for response from servers listening on the multicast address. Once a responding server is found, use connect to turn the client into a unicast one, and start point-to-point communication with the discovered server.

#
UdpClient::fd

fn UdpClient::fd(self : UdpClient) -> Int

#
UdpClient::recv

async fn UdpClient::recv(self : UdpClient, buf : FixedArray[Byte], offset? : Int, max_len? : Int) -> Int

Receive packet from a UDP client. For udp.recv(buf, offset~, max_len~), at most max_len bytes of data will be written to buf, starting from offset. The number of received bytes will be returned.

UDP is a datagram based protocol, and recv will always receive exactly one UDP packet. If the buffer is smaller than the received packet, the rest of the packet will be lost.

At most one task can read from a UDP client at any time. To allow multiple reader, use a worker task for reading and use @async.Queue to distribute the data.

#
UdpClient::recvfrom

async fn UdpClient::recvfrom(self : UdpClient, buf : FixedArray[Byte], offset? : Int, max_len? : Int) -> (Int, Addr)

Similar to recv, but additionally return the address of the packet's sender. Unicast UdpClient can only receive traffic from the target server, so this is mainly useful for multicast clients.

#
UdpClient::send

async fn UdpClient::send(self : UdpClient, buf : Bytes, offset? : Int, len? : Int) -> Unit

Send data through a UDP client.

UDP is a datagram based protocol, every call of send will send exactly one packet.

At most one task can write to a UDP client at any time. To allow multiple writers, use a worker task for reading and use @async.Queue to gather the data.

#
UdpClient::set_multicast_interface

fn UdpClient::set_multicast_interface(self : UdpClient, addr : Addr) -> Unit raise

Set the outgoing interface used for sending multicast packets with this client.

This function is IPv4-only. For IPv6, use set_multicast_interface_v6 instead.

#
UdpClient::set_multicast_interface_v6

fn UdpClient::set_multicast_interface_v6(self : UdpClient, interface : String) -> Unit raise

Set the outgoing interface used for sending multicast packets with this client. The interface is provided via IPv6 zone suffix index. It can either be a decimal string for a raw interface index, or a network interface name.

This function is IPv6-only. For IPv4, use set_multicast_interface instead.

#
UdpClient::set_multicast_loopback

fn UdpClient::set_multicast_loopback(self : UdpClient, loopback : Bool) -> Unit raise

Set the multicast loopback option for this client. On Windows: make sure multicast packets sent from local machine is not received by this client. On other systems: make sure multicast packets sent by this client are not routed back to local machine

Note that the loopback setting does not apply for localhost traffic.

#
UdpClient::set_multicast_ttl

fn UdpClient::set_multicast_ttl(self : UdpClient, ttl : Int) -> Unit raise

Set the multicast TTL (or hop limit for IPv6) for this client. ttl=0 means packet never goes out of local machine. ttl=1 means packet never goes out of local subnet.

#
UdpServer

pub struct UdpServer {
addr : Addr
// private fields
}

A UDP server bound to a listen address and receive packets from clients.

UDP does not really have a clear client/server distinction, especially when multicast is involved. The essence of UdpServer is a UDP socket with a fixed/well-known port.

#
UdpServer::UdpServer

#alias(new, deprecated="`new` is deprecated, use `UdpServer` instead")
async fn UdpServer::UdpServer(addr : Addr, dual_stack? : Bool) -> UdpServer

Create a UDP server listening at addr.

If addr is the IPv6 wildcard address [::] and dual_stack is true (true by default), the server will work in dual stack mode, receiving packets from both IPv4 peers and IPv6 peers. The address of IPv4 peers are represented via IPv4-mapped IPv6 address.

If addr is not [::], dual_stack is ignored.

If the port of addr is zero, the server will be bound to a random port, assigned by the operating system. The actual listen address can be retrieved via .addr().

The server will only receive packets whose destination address matches addr. So if you want to receive multicast traffic, the server should be bound to 0.0.0.0 or [::]. DO NOT bind the server to a multicast address: this is not supported on Windows. For multicast-only servers, use UdpServer::multicast() instead.

#
UdpServer::addr

#deprecated("use `.addr` instead")
fn UdpServer::addr(self : UdpServer) -> Addr

Get the listen address of a UDP server.

#
UdpServer::close

fn UdpServer::close(self : UdpServer) -> Unit

#
UdpServer::fd

fn UdpServer::fd(self : UdpServer) -> Int

#
UdpServer::join_multicast_group

fn UdpServer::join_multicast_group(self : UdpServer, multi_addr : Addr, interface_addr? : Addr) -> Unit raise

Let the server join multicast group at address multi_addr, via interface interface_addr. interface_addr defaults to a random interface chosen by the OS. Only the IP part of multi_addr and interface_addr matters, the port is irrelevant.

Note that join_multicast_group is mainly about IGMP related stuff, it does not serve as a packet filter. A UDP server can receive all packets whose destination match the server's address. Some consquence of this:

  • The port to receive multicast traffic is determined on server creation

  • if the server is bound to a specific interface, it will not receive any multicast traffic, because multicast traffic has special destination IP

  • multicast-only server created by UdpServer::multicast cannot join multiple multicast groups with different IP address.

This function is IPv4 only. For IPv6 multicast, use join_multicast_group_v6 instead.

#
UdpServer::join_multicast_group_v6

fn UdpServer::join_multicast_group_v6(self : UdpServer, multi_addr : Addr, interface? : String) -> Unit raise

Let the server join multicast group at address multi_addr, via interface interface. interface, if provided, should use IPv6 zone suffix syntax, meaning it can either be a decimal string for raw interface index, or a network interface name. interface defaults to "0", meaning a default output interface chosen by the OS. For interface-local/link-local multicast packets, the interface must be explicitly specified. Only the IP part of multi_addr matters, the port is irrelevant.

Note that join_multicast_group is mainly about IGMP related stuff, it does not serve as a packet filter. A UDP server can receive all packets whose destination match the server's address. Some consquence of this:

  • The port to receive multicast traffic is determined on server creation

  • if the server is bound to a specific interface, it will not receive any multicast traffic, because multicast traffic has special destination IP

This function is IPv6 only. For IPv4 multicast, use join_multicast_group instead.

#
UdpServer::multicast

async fn UdpServer::multicast(multi_addr : Addr, interface_addr? : Addr) -> UdpServer

Create a multicast-only UDP server listening for multicast packets towards multi_addr. The server will only receive packets towards multi_addr, no unicast traffic will be received.

Multicast only servers created via UdpServer::multicast are shared. There can be multiple such server listening on the same address at the same time.

The server will automatically join the IP multicast group at multi_addr, using interface interface_addr (defaults to a random interface chosen by the OS). Only the IP part of interface_addr matters, the port is irrelevant.

Due to OS limitation, currently every multicast-only server can listen for only one multicast IP. Calling join_multicast_group on server created by UdpServer::multicast with different address simply does not work. Users can join the same IP with a different interface using join_multicast_group, though.

Currently this function is IPv4 only. There is no simple way to implement multicast-only IPv6 socket on Linux/MacOS.

#
UdpServer::recvfrom

async fn UdpServer::recvfrom(self : UdpServer, buf : FixedArray[Byte], offset? : Int, max_len? : Int) -> (Int, Addr)

Receive packet from a UDP server, and obtain the source address of the packet. For udp.recvfrom(buf, offset~, max_len~), at most max_len bytes of data will be written to buf, starting from offset. The number of received bytes and the source address of the packet will be returned.

UDP is a datagram based protocol, and recv will always receive exactly one UDP packet. If the buffer is smaller than the received packet, the rest of the packet will be lost.

At most one task can read from a UDP server at any time. To allow multiple reader, use a worker task for reading and use @async.Queue to distribute the data.

#
UdpServer::sendto

async fn UdpServer::sendto(self : UdpServer, buf : Bytes, addr : Addr, offset? : Int, len? : Int) -> Unit

Send a packet to addr through a UDP server.

UDP is a datagram based protocol, every call of send will send exactly one packet.

At most one task can write to a UDP server at any time. To allow multiple writers, use a worker task for reading and use @async.Queue to gather the data.

#
UdpServer::set_multicast_interface

fn UdpServer::set_multicast_interface(self : UdpServer, addr : Addr) -> Unit raise

Set the outgoing interface used for sending multicast packets with this server.

This function is IPv4-only. For IPv6, use set_multicast_interface_v6 instead.

#
UdpServer::set_multicast_interface_v6

fn UdpServer::set_multicast_interface_v6(self : UdpServer, interface : String) -> Unit raise

Set the outgoing interface used for sending multicast packets with this client. The interface is provided via IPv6 zone suffix index. It can either be a decimal string for a raw interface index, or a network interface name.

This function is IPv6-only. For IPv4, use set_multicast_interface instead.

#
UdpServer::set_multicast_loopback

fn UdpServer::set_multicast_loopback(self : UdpServer, loopback : Bool) -> Unit raise

Set the multicast loopback option for this server. On Windows: make sure multicast packets sent from local machine is not received by this server. On other systems: make sure multicast packets sent by this server are not routed back to local machine

Note that the loopback setting does not apply for localhost traffic.

#
UdpServer::set_multicast_ttl

fn UdpServer::set_multicast_ttl(self : UdpServer, ttl : Int) -> Unit raise

Set the multicast TTL (or hop limit for IPv6) for this client. ttl=0 means packet never goes out of local machine. ttl=1 means packet never goes out of local subnet.

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io