Next: , Previous: Interacting, Up: Using Networking



2.5 Setting Up a Service

The preceding programs behaved as clients that connect to a server somewhere on the Internet and request a particular service. Now we set up such a service to mimic the behavior of the `daytime' service. Such a server does not know in advance who is going to connect to it over the network. Therefore, we cannot insert a name for the host to connect to in our special file name.

Start the following program in one window. Notice that the service does not have the name `daytime', but the number `8888'. From looking at /etc/services, you know that names like `daytime' are just mnemonics for predetermined 16-bit integers. Only the system administrator (root) could enter our new service into /etc/services with an appropriate name. Also notice that the service name has to be entered into a different field of the special file name because we are setting up a server, not a client:

     BEGIN {
       print strftime() |& "/inet/tcp/8888/0/0"
       close("/inet/tcp/8888/0/0")
     }

Now open another window on the same machine. Copy the client program given as the first example (see Establishing a TCP Connection) to a new file and edit it, changing the name `daytime' to `8888'. Then start the modified client. You should get a reply like this:

     Sat Sep 27 19:08:16 CEST 1997

Both programs explicitly close the connection.

Now we will intentionally make a mistake to see what happens when the name `8888' (the so-called port) is already used by another service. Start the server program in both windows. The first one works, but the second one complains that it could not open the connection. Each port on a single machine can only be used by one server program at a time. Now terminate the server program and change the name `8888' to `echo'. After restarting it, the server program does not run any more, and you know why: there is already an `echo' service running on your machine. But even if this isn't true, you would not get your own `echo' server running on a Unix machine, because the ports with numbers smaller than 1024 (`echo' is at port 7) are reserved for root. On machines running some flavor of Microsoft Windows, there is no restriction that reserves ports 1 to 1024 for a privileged user; hence, you can start an `echo' server there.

Turning this short server program into something really useful is simple. Imagine a server that first reads a file name from the client through the network connection, then does something with the file and sends a result back to the client. The server-side processing could be:

     BEGIN {
       NetService = "/inet/tcp/8888/0/0"
       NetService |& getline
       CatPipe    = ("cat " $1)    # sets $0 and the fields
       while ((CatPipe | getline) > 0)
         print $0 |& NetService
       close(NetService)
     }

and we would have a remote copying facility. Such a server reads the name of a file from any client that connects to it and transmits the contents of the named file across the net. The server-side processing could also be the execution of a command that is transmitted across the network. From this example, you can see how simple it is to open up a security hole on your machine. If you allow clients to connect to your machine and execute arbitrary commands, anyone would be free to do `rm -rf *'.