1.146 class socket

Class socket provides an interface to Unix sockets. A Unix socket is a (network) communication end-point. Normally one process creates a socket at a specified address (see below). Other processes may use a socket to socket->connect to the created socket. After the connection has been established, a two-way text-based communication channel is available.

Below is a first, very simple example:

?- new(X, socket('~/xpce-socket')),
   send(X, input_message, message(@pce, write, @arg1)),
   send(X, listen).

In another xpce process running on the same machine we can now do

?- new(X, socket('~/xpce-socket')),
   send(X, connect),
   send(X, format, 'Hello There\n'),
   send(X, close).

Sockets addresses may be internet addresses as (allowing for communication between machines) and unix-domain addresses, allowing for communication between processes running on the same machine. See also socket->initialise.

We distinguish between server sockets and client sockets. After the connection has been established there is no difference between the two. Below we describe the process to establish a connection:

  1. Create a server socket. The address is either a file or a port number. See socket->initialise. The stream->input_message is called whenever there is input on the socket; the socket->accept_message is called whenever a client makes an attempt to socket->connect to this socket.
  2. Invoke socket->listen. This will make the socket listen to requests from other processes.
  3. (In the other process) Create a client socket. The address is either the same file as created by the server or a tuple consisting of an internet node name and a port number.
  4. Invoke socket->connect. Provided the address is right this will cause the server socket to start socket->accept. socket->accept will object<-clone the server socket and run the socket->accept_message with @receiver bound the the server socket and @arg1 bound to the clone. After this, a communication channel exists between the cloned server and the client socket. Data is sent to the socket using stream->append or stream->format. Whenever data is available, stream->input_message is called to handle this data. Class process handles input from its inferior process using the same mechanism.

    The Unix program xpce-client(l) may be used to connect to xpce-processes. See also telnet(1). The sources of xpce-client may be found in xpce/src/unx-client.c. They may be used as a starting point for other unix programs that wish to communicate to xpce.

    See also class stream.

    The library file pce_server defines pce_server/1 to create a server mode.

1.146.1 Instance variables

socket <-> accept_message: code*
This message is executed after a server socket has accepted a new connection. It receives the following arguments:
@receiver The original socket
@arg1 The object<-clone’d socket for the new connection.

This message may be used to deny the client access by object->free’ing the new socket (@arg2).

See also stream->input_message.

socket <- address: file|tuple|int*
Address for the connection end-point. If the socket was created as a server socket on inet address 0 (this machine, port number 0), the socket->listen call will replace the socket<-address with the actually used port number.
stream <- input_message: code*
Whenever there is input available, this message will be called with
@receiver = the socket
@arg1 = a new string object holding the data

See also stream<-read_line.

Defaults: The default input_message is @nil. In this case data may only be read using stream<-read_line.

socket <- status: {idle,listen,accepted,connected}
Status of the associated socket. The initial socket<-status of a socket is idle. A server socket waiting for connections has status listen. An cloned server socket handling a connection has status accepted and finally, an open client socket has socket<-status connected.

See also socket->listen, and socket->connect.

1.146.2 Send methods

socket ->connect:
Connect with server socket. First, the socket must be created with the appropriate address. To connect a client to a Unix-domain socket, use:
new(S, socket(File)),
send(S, connect),
...

To connect to an inet domain socket, use:

new(S, socket(tuple(Host, Port))),
send(S, connect),
...

socket->connect is a no-op if socket<-status is already connected.

socket ->end_of_file:
Sent by the system when end-of-file is reached on the input. If the socket has socket<-status: accepted (i.e. it is a clone of a server socket handling a connection), the default is to object->free the socket object.
socket ->initialise: address=file|tuple|int*, domain=[{unix,inet}]
Create a server or client socket. The address argument is either a file object for Unix domain sockets or a port-number of inet-domain (TCP/IP) sockets. For inet-domain server sockets the address argument is the port-number or 0 (zero) to select an arbitrary free socket. The selected port can be requested using socket<-address.

Unix-domain sockets appear as an entry in the filesystem and are only supported on Unix systems.

After a socket has been created and the appropriate attributes (notably stream->input_message) have been specified the socket is activated using socket->listen for server sockets and socket->connect for client sockets.

socket ->listen: accept_message=[code]*, backlog=[{1..5}], reuse=[bool]
Prepare the socket to listen for connections. The argument replaces the socket->accept_message when specified. The second argument is the backlog. It specifies how many pending requests for connections are tolerated. Any new connect request will be denied. The default is 5.

If the reuse argument is @on, the system tries to reuse the specified port, dispite it still being in use. This option is needed to restart a service at the same -well known- port after an dirty shut-down. If you are security minded, check the internet on setsockopt() for the option SO_REUSEADDR before activating this option.

If an inet domain socket was created with its port specified as 0, the system will select an available port. The actually used port can be requested from the socket object using socket<-address after this method completed successfully.

1.146.3 Get methods

socket <-peer_name: -> name|tuple
Returns the address of the socket at the other side of the connection. The socket must be connected, which implies it has executed a successful socket->connect (client) or is a cloned socket from a socket in socket->listen mode (server, see socket<-clients and socket->accept_message).

If the socket is in the Unix socket<-domain, the return value is a name describing the file (which will be the same as the absolute path-name of the file used to create the socket).

If the socket is in the inet socket<-domain, the return value is a tuple object holding a name describing the internet address of the socket at the other end in decimal numeric notation and an integer describing the port.