10.21 Socket I/O—library(sockets)

This library package defines a number of predicates for communicating over sockets.

To create a (bi-directional) stream connected to a remote server, use socket_client_open/3.

To open a port for remote clients to connect to, use socket_server_open/[2,3] and to open a stream to a connecting client, use socket_server_accept/4.

To be able to multiplex input and output from several streams (not necesessarily socket streams) and incoming connections, use socket_select/7.

When opening a client or server socket a socket address needs to be specified. The address specifies the address family and family-specific information. The following formats are supported for socket addresses:

This specifies the address for and ordinary internet socket (AF_INET or AF_INET6). Nodename is the internet address of the remote host, as an atom, something like 'www.sics.se' or ''. The empty nodename '' (the default), has special meaning, see the documentation for socket_client_open/3 and socket_server_open/[2,3]. Servname is either a port number as an atom of decimal digits or as an integer, e.g. '80', or 80; alternatively some well known port names can be used, e.g. 'http'. The set of well known port names is OS specific, portable code should use integer port numbers. Servname can also be a variable when opening a server socket with socket_server_open/[2,3]. In this case a available port is assigned automatically and Servname is bound to it.
A Unix domain (AF_UNIX) socket is opened at the specified file system location. This is only supported on Unix-like platforms. Path is a file-name and is passed to absolute_file_name/2. There may be platform-specific restrictions on the length of the resulting pathname and the file system containing it.

All streams below can be read from as well as written to. All I/O predicates operating on streams can be used, for example get_code/2, get_byte/2, read/2, write/2, format/3, current_stream/3, etc. The predicates that create streams take options similar to open/4, e.g. to specify whether the stream is binary (the default) or text.

socket_client_open(+Addr, -Stream, +Options)
Creates a stream Stream connected to address Addr. See above for the allowed address formats. If the nodename is empty ('') then a connection is made to the local machine.

The stream is created using options from Options. Supported options include:

Create a binary stream (the default).
Create a text stream. The default encoding is Latin 1.
end of file action, as for open/4.

To create a binary stream to some web server www.sics.se, you would do e.g.

          | ?- socket_client_open('www.sics.se':80, Stream, [type(binary)]).

or, to make a text (Latin 1) stream to a daytime service in Hong Kong you could do:

          | ?- socket_client_open('stdtime.gov.hk':daytime, S, [type(text)]),
               read_line(S, L),
               format('~s', [L]).

See the source code for library('linda/client') for a simple client.

socket_server_open(?Addr, -ServerSocket, +Options)
Create a server socket ServerSocket that listens on address Addr. See above for the allowed address formats. If the nodename is empty ('') then any remote client machine is allowed to connect unless the option loopback(true) is also specified. Addr can specify an internet address where the port is a variable in which case a free port number is used and Port is bound to it. The common case is that Addr is a numeric port number or a variable that becomes bound to a free port number.

The created server socket should be closed with socket_server_close/1 eventually. Incoming connection can be accepted with socket_server_accept/4 and waited for with socket_select/7. See the source code for library('linda/server') for a simple server that uses this predicate.

Options is a list of options, currently

Bool is either true or false (the default). If true then allow reuse of local addresses. For internet sockets this corresponds to the SO_REUSEADDR socket option. For unix domain sockets this means that the file will be deleted, if present, before opening.
Bool is either true or false (the default). If true then the nodename of an internet address will be treated as a numerical address and no name lookup will be performed.
Bool is either true or false (the default). If true then the servname of an internet address will be treated as a numerical port number and no lookup of well known port names will be performed.
Bool is either true or false (the default). If true then the nodename will be ignored and the socket will only listen to connection from the loopback device, i.e. the local machine.

socket_server_open(?Port, -ServerSocket)
The same as socket_server_open(Port, ServerSocket, []).
socket_server_accept(+ServerSocket, -Client, -Stream, +StreamOptions)
The first connection to socket ServerSocket is extracted, blocking if necessary. The stream Stream is created on this connection using StreamOptions as for socket_client_open/3. Client will be unified with an atom containing the numerical Internet host address of the connecting client. Note that the stream will be type(binary) unless type(text) is explicitly specified.
Close the server socket ServerSocket and stop listening on its port.
socket_select(+ServerSockets,-SReady, +ReadStreams,-RReady, +WriteStreams,-WReady, +Timeout)
Check for server sockets with incoming connections (i.e. ready for socket_server_accept/4), streams on ReadStreams ready for input, and streams on WriteStreams ready for output. The streams can be any kind of streams, they need not be socket streams. The ready server sockets are returned (in the same order) in SReady, the ready input streams in RReady, and the ready output streams in WReady.

An input (output) stream is ready for input (output) when an item can be read (written) without blocking. An item is a character for text streams and a byte for binary streams. Note that a stream is considered ready for I/O if the corresponding I/O operation will raise an error (such as if the stream is past end of stream).

Each entry in the input lists ServerSockets, ReadStreams, and WriteStreams can be either a server socket or stream respectively or a term Term-Entry where Entry is the server socket or stream and Term is some arbitrary term used for book-keeping. If an entry is associated with a term in this way then so will the corresponding ready entry.

If TimeOut is instantiated to off, the predicate waits until something is available. If TimeOut is a nonzero number (integer or floating point), then the predicate waits at most that number of seconds before returning. For backward compatibility, if TimeOut is S:U the predicate waits at most S seconds and U microseconds. If there is a timeout, all ready lists are unified with [].

See the source code for library('linda/server') for a simple server that uses this predicate.

HostName is unified with the fully qualified name of the machine that the process is executing on. The call will also succeed if HostName is instantiated to the unqualified name of the machine in lower case.

Send feedback on this subject.