Now, let's look at a further feature of the POSIX environment. It also supports writing network programs, that communicate over the Internet using sockets. A socket can be thought of as a two-way communication channel, consisting of both an RFile and a WFile.

Two network programs, which execute on different machines, may connect over the network and communicate using a socket. Typically, one of the programs will be a server and the other a client. Here is a trivial server, the EchoServer. This server waits indefinitely for clients to connect on port 12345. When a client connects, the server starts a session, where client input rows are echoed back to the client, prefixed by a line number. Several clients may be served concurrently and line numbering is independent for each client.

module EchoServer where

import POSIX

port = Port 12345

root w = do
    env = new posix w
    env.inet.tcp.listen port (server env.stdout)

server logfile sock = class

   n := 1

   p = show sock.remoteHost

   log str = logfile.write ('[':str ++ "]\n")

   echo str = action
      sock.outFile.write (show n ++"> "++str)
      n := n+1

   close = request
      log (p ++ " closing")
      result ()

   neterror str = action log ("Neterror: "++str)

   established = action
      log ("Connected from " ++ p)
      sock.inFile.installR echo

   result Connection{..}

Comments to the code:

In order to let you run the server, we provide a simple client, TCPClient. We do not list the code here; you may review it in TCPClient.t. The client accepts a host name and a port number as command line arguments and connects to a server on that address. When a connection is established, the client accepts user input lines, sends them to the server and displays replies obtained on the screen.