This type of communication is very similar to pipes, the stream communication is reliable and there are no boundaries between the messages. Stream sockets always require explicit connection from both communicating processes.
After a socket is created with the socket/3 predicate, one of the processes, the server, gives it a name and waits for a connection. The other process uses the same name when connecting to the former process. After the connection is established, both processes can read and write on the socket and so the difference between the server and the client disappears. The socket addresses contain the host name and the port number. Since one port number identifies the socket on a given host, the process cannot itself specify the port number it wants to use because it can be already in use by another process. Therefore, the safe approach is to use the default and let the system specify the port number, which is achieved by leaving the port uninstantiated. Since the host is always known, it can also be left uninstantiated. The client, however, has to specify both the host name and the port number:
server: [eclipse 10]: socket(internet, stream, s), bind(s, X). X = acrab5 / 3789 yes. [eclipse 11]: listen(s, 1), accept(s, From, news). <blocks waiting for a connection> client: [eclipse 26]: socket(internet, stream, s), connect(s, acrab5/3789). yes. [eclipse 27]: printf(s, "%w. %b", message(client)), read(s, Msg). server: From = acrab4 / 1627 yes. [eclipse 12]: read(news, Msg), printf(news, "%w. %b", message(server)). Msg = message(client) yes. client: Msg = message(server) yes.