This module is the portable socket layer for TCP and UDP on IPv4 and IPv6, so a caller listens, connects, and transfers bytes through the same types on every supported platform. IPv4 and IPv6 are address content rather than separate socket classes, and unicast, broadcast, and multicast UDP use one datagram socket type.
Endpoint is the address value both protocols use: it names a host and a service port, it does not open a socket, and listen, bind, connect, and send destinations all take endpoints. Name resolution happens when a socket uses the endpoint, not when the value is constructed.
Sockets take part in the System I/O model. A server that waits for TCP connections is a Selectable, which reports pending peers and does not transfer bytes, while TCP and UDP sockets that transfer bytes are IODevice types and use the same operations as files and pipes: blocking read() and write(), or beginRead() and beginWrite() with an EventLoop. The I/O device and event-loop chapters document those operations; this module adds the network types that use them.
Synchronous and asynchronous work use the same socket object. Asynchronous work attaches with setActive() so an EventLoop can monitor the socket, but the loop does not own it: the code that creates the socket keeps it alive while it is attached, and destroys or closes it only when no operation is still waiting on the loop.
When listen() or bind() finds the local address already occupied, the operation throws AddressInUse, and when a remote host cannot be reached, connect() and related operations throw AccessFailed. Option values configure listen, connect, bind, and send, but they do not open a socket and they do not own one.
TCP is a connected byte stream between two endpoints, in which a TcpServer listens and a TcpSocket is the stream, created by accepting a pending connection or by connecting to a remote endpoint.
UDP is datagram I/O on a single UdpSocket, which sends and receives unicast, broadcast, and multicast datagrams.
The rest of this chapter is the address value, then the TCP stream model, then the UDP datagram model.
This chapter covers:
Endpoint is the copyable address value that TCP and UDP operations use: it names a host and a service port, but it does not open a socket, and constructing one does not start a connection or a listen.
A host string and a port number construct it, and the host may be a DNS name or a numeric IPv4 or IPv6 address. Name resolution happens when a socket uses the endpoint, not when the value is created, so an invalid name fails on listen, bind, or connect rather than on construction.
Factory functions build the IPv4 and IPv6 any and loopback addresses, and the IPv4 broadcast address, for a port, and those addresses do not perform name resolution. The any-address is the local wildcard used to listen or bind on every local interface, loopback is the host itself, and the IPv4 broadcast address is the send destination for UDP broadcast.
toString() formats the endpoint for display, clear() resets it to an empty address, and copy and assignment duplicate the address, not a socket.
The example constructs a named host-and-port endpoint and an IPv4 any-address for a port, so the first is a remote or named host and the second is a local wildcard.
TCP is a connected byte stream between two endpoints, implemented by two types: TcpServer listens on a local endpoint and reports pending peers, and TcpSocket is the stream that transfers bytes, whether it is the client side of a connect() or the accepted side of a pending server connection.
A server listen() binds the local endpoint and waits for peers. TcpSocket::accept() takes one pending connection and makes that socket the accepted stream, while TcpSocket::connect() reaches a remote endpoint and makes that socket the client stream. After the stream is up, read() and write() are the inherited I/O-device operations, blocking or asynchronous.
TcpServer is a Selectable, not an IODevice, so it does not read or write, whereas TcpSocket is an IODevice. Listen and connection settings live in TcpServerOptions and TcpSocketOptions, which configure an operation but do not open a socket.
The example is the two-type model on one thread: listen() queues incoming connections, connect() completes against that queue, accept() takes the pending stream, and the bytes then move through the inherited device operations.
TcpServer is the listening Selectable in the TCP model: it binds a local endpoint and reports pending peers, but it is not an IODevice and it does not read or write bytes. A TcpSocket takes each connection.
listen() binds the local endpoint and waits for peers, and if that address is already occupied the call throws AddressInUse. A second listen() closes the previous listen first, so the server holds at most one local binding. The constructors create a closed server, attach one to an EventLoop, or listen immediately on an endpoint.
TcpServerOptions configure the listen; they do not open a server. The accept backlog is the number of pending connections the server will queue, and deferred accept, when set to a positive number of seconds, may wait until the peer sends data before reporting the connection. A negative deferred-accept value leaves that setting unset.
Asynchronous accept requires an attached event loop. beginAccept() waits for the next pending connection, and connectionPending() is emitted when a peer is ready. There is no matching end-accept: a TcpSocket takes the connection with accept(). The server must be attached before beginAccept(), and after the slot takes the connection, beginAccept() is called again to wait for the next peer.
close() stops listening and accepting. The caller owns the server, and attaching it to a loop does not transfer ownership.
The example is the pending-connection slot. The acceptor is Connectable so it can bind connectionPending() to onPending(), and when the signal fires, accept() takes the stream into a TcpSocket that the acceptor owns.
TcpSocket is the connected TCP IODevice, and the same type is the client side of a connect() and the accepted side of a pending TcpServer connection. After the stream is up, read() and write() are the inherited device operations, blocking or asynchronous.
connect() reaches a remote endpoint and makes this socket the client stream, throwing AccessFailed if the host is not reachable, while accept() takes a pending connection from a listening server and makes this socket the accepted stream. A socket is one side or the other, not both at once, because connect() and accept() close any previous connection first.
beginConnect() starts an asynchronous connect, which requires the socket to be attached to an event loop. connected() is emitted when the attempt finishes, and endConnect() completes it, throwing AccessFailed if the host is not reachable. isConnected() reports whether the stream is up, and localEndpoint() and remoteEndpoint() write the two sides of the connection.
TcpSocketOptions configure the connection but do not open a socket. Keep-alive, when set to a non-negative interval in seconds, enables periodic probes on the stream, and a negative value leaves keep-alive unset.
The example is an asynchronous client connect, in which the slot calls endConnect() and then writes through the inherited device operation. The accept path is the TcpServer pending-connection slot.
UDP is datagram I/O on a single UdpSocket type, which sends and receives unicast, broadcast, and multicast datagrams. It is an IODevice: after a local bind or a send destination is set, read() and write() are the inherited device operations, blocking or asynchronous, except that each write() sends one datagram and each read() receives one datagram rather than a TCP-style byte stream.
Three operations set where datagrams go and where they come from. bind() sets the local endpoint that receives datagrams, connect() associates a remote peer so writes go to that peer and reads come from it, and setTarget() sets a send destination without associating the socket, which is the path broadcast and multicast sends use. A socket may bind and still set a target, which is how a receiver that also sends to a group is set up.
A socket joins a multicast group to receive that group's datagrams, which means bind first, then join. UdpSocketOptions enable broadcast and set the hop limit; those values configure an operation, but they do not open a socket.
UdpSocket is the datagram IODevice for unicast, broadcast, and multicast, so one type covers all three modes. After a local bind or a send destination is set, read() and write() are the inherited device operations, blocking or asynchronous, except that each write() sends one datagram and each read() receives one datagram.
bind() sets the local endpoint that receives datagrams, throwing AddressInUse if that address is already occupied and AccessFailed if the host cannot be used. connect() associates a remote peer so writes go there and reads come from it, while setTarget() sets a send destination without associating the socket, which is the path broadcast and multicast sends use. connect() and setTarget() throw AccessFailed when the host is not reachable.
beginBind() and beginConnect() start those operations on an attached event loop and return true when the operation completed immediately. bound() and connected() are emitted when the attempt finishes, and endBind() and endConnect() complete it. The socket must be attached before either begin method is called. isBound() and isConnected() report the current associations, localEndpoint() writes the local side, and remoteEndpoint() is the associated peer.
Broadcast send sets the broadcast option and uses the IPv4 broadcast endpoint as the target, while multicast send uses a multicast group address as the target. To receive a group's datagrams, bind first, then joinMulticastGroup(). UdpSocketOptions also set the hop limit; those values configure an operation, but they do not open a socket.
The first example is asynchronous unicast: one socket binds the local any-address, the other connects to loopback, and each slot completes the begin operation before I/O. The second example is a broadcast send, and the third binds, joins a group, and sends to that group.