Corporate and Professional Publishing Group


An Engineering Approach to Computer Networking

by S. Keshav

ISBN 0-201-63442-2 * Hardcover * 688 pages * 1997


Book Description Preface Glossary Bibliography Solutions Slides Simulator Exercises Errata Cover (73K) Ordering Information C&P Welcome Page.


Sockets

Goal

In this assignment you will learn to use TCP/IP and sockets for communicating over the Internet. The goal is to familiarize you with socket programming, and give you some intuition on building interpreted environments such as that provided by the Java virtual machine.

Outline

You will write two programs for this assignment. One is a client program (called rcmd, for "remote command"), and the other is a server (called rcmdd, for "remote command daemon") . The client sends the server a one-byte message that contains either the command "0" or the command "1". On receiving message "0", the server executes the Unix "ls" command, and returns the result. On receiving message "1", the server executes the Unix "date" command, and returns the result. The server terminates after executing the command, and the client terminates after printing the result on the screen.

Details

The client takes three arguments: the name of the server machine, the port number to which it should connect, and the command (in that order). It first translates from the servers name to its IP address, using the gethostbyname system call. It uses the IP address to fill in a sockaddr_in structure, then opens a socket to the server using the socket and connect system calls. Next, it sends the command as a 1-byte ASCII string, using the write system call. Finally, it reads the reply, using the read call in a loop, and displays the result on the screen using the write system call.

The server takes one argument, which is the port number on which it listens for an incoming command. It fills in a sockaddr_in structure with the port number, with the incoming address field (s_addr) field set to INADDR_ANY. It uses the socket, bind, and listen system calls to create a socket, bind the port number to it, and to listen for a request. On getting the request, it accepts it, reads the message sent to it, executes the corresponding command using the Unix system system call and writes the result to a temporary file. It then opens the file for reading, reads the result, and uses the write call to write the results back to the client.

TCP/IP does not provide message boundaries. So, the client does not know how long a result to read from the server. To get around this, the first 10 bytes of the server's message are the length of the reply, in ASCII. For example, if the length of the reply is 15 bytes, the first 10 bytes would be ASCII 1, ASCII 5 and eight \0s (use the sprintf call to convert from binary to ASCII).

Here are some files to get you started. rcmd is an executable that implements the client and rcmdd implements the server. These executables will work only on SunOS machines. Here are the Solaris executables: rcmd and rcmdd. (Note to instructors: contact me to get the source code so that you can create your own binaries).

The makefile will help you make the executables (here is the makefile for a Solaris machine). You can run the existing rcmd and rcmdd with each other, then write your own rcmd, testing it against the rcmdd already provided. Then, write rcmdd, testing it with the rcmd provided. If these interoperate, so should your rcmd and rcmdd.

A sample run

1. Run the server from a directory for which you have write permission

2. From another window run rcmd as

3. There is nothing special about the number 5000, it can be anything larger than 1024. Try running it with other port numbers.

4. The server and client can run on different machines. Run rcmdd on machine A then login to machine B, and run rcmd as

Grading

We will test your implementations of rcmd and rcmdd with the ones we provided. You can write your implementations of the two commands in any language you want, as long as you have the proper makefile to make your binary. To submit the assignment, use the tar command to package your directory containing the source code and the makefile, and the uuencode command to convert the tar file to ASCII. Then, mail the uuencoded file to the TA, with a subject line reading "Assignment 1". If you do not know what tar and uuencode do, read the man pages.

Hints

  1. Probably the best introduction to socket hacking is at http://world.std.com/~jimf/papers/sockets/sockets.html.
  2. Remember to convert from host byte order to network byte order using the htons, htonls, ntohs, and ntohl calls, particularly when filling up the fields in the sockaddr_in structure.
  3. Remember to error check each system call. Use perror to notify the user of errors.
  4. When a server binds to a port number, the number cannot be used for a while, even if the server terminates (this is called lingering). To work around this, every time you start the server, remember to use a port number different from one you have used in the recent past. You can see which port numbers are currently in use with the /usr/etc/netstat command.

Java and interpreted environments

While it would be trivial to extend rcmd and rcmdd to allow rcmd to send an arbitrary command encoded in ASCII and for rcmdd to execute it, this is not particularly safe. What we have done here it to allow rcmdd to execute only safe operations, such as date and ls. We do so by interpreting the incoming commands, mapping them into safe commands. This is the basic idea behind Java, where the "java virtual machine" executes Java programs by interpreting them. Since we can restrict the actions of the interpreter to safe ones, this also limits the damage a Java applet can cause at the client browser. Once you have written rcmd and rcmdd, you have all the tools to build your own version of Java (at least the networking part)!