Homework: 22C:178 & 055:134

Computer Communications Fall 1998

Assignment 6

[due 20 October]

What if a program needs to simultaneously wait on two sockets connected to ports? Consider a program that has two sockets named Asock and Bsock, both of which have been bound (using bind or another method) to ports. If the program tries to recvfrom the socket named Asock, it will wait for a datagram to arrive at the port bound to Asock. In the meantime, while it is waiting on Asock, a datagram could arrive to Bsock's port -- but the program won't be able to detect this, because it is waiting only for Asock to have data!

How can we resolve this? One technique would be to use fork() and devote concurrent processes to each input port. But we use a different -- and simpler -- strategy for this homework. Unix provides a system call to determine whether or not your program would wait on a port before your program attempts to read() or recvfrom(). This system call is the select() call, documented by the man select man pages.

The unix documentation for select() is not very thorough or helpful to get started programming, so it is best to see an example. The udpserv3.c program shows a version of the UDP server used in earlier homeworks, but expanded to have five input ports. This program will wait simultaneously on these five input ports and only read from one of them when data is available. Therefore the program does not get ``stuck'' as in the example above. You should use the same select() technique (with FD_SET, FD_ZERO, and FD_ISSET) in your code for for this homework.

Other ``tools'' for this homework are programs that generate data, take parameters from the command line, and send datagrams to ports. The parms.c program is a trivial example showing the relation between command line parameters and a C program. Compile parms.c using the command

gcc parms.c -o parms
and then try the following commands:
parms this is a test
parms this ~/file is "a second" test
If you are curious about the results, please ask the TA questions about how command-line parameters work.

Another tool is the supply.c program. It is just a program to generate lots of data, sending it to standard output. Try the following:

gcc supply.c -o supply
supply 4 X
You should see 4,096 characters output (all X's) in lines of 64 bytes each. To verify this, examine the output of the command
supply 4 X | wc
which pipes the output from the supply program into the input of the wc utility, which is a standard unix utility to count the number of lines, bytes, and words from its input (of course, man wc explains this utility).

Finally, we have a program to act as the client to the server. The program gendata.c is similar to the udpcli.c program we used in previous homeworks. It, however, is more flexible because the port numbers are not built in. Let's suppose you still have the program udpserv in your directory. If you open two windows, you can start udpserv in one window and gendata in the other window. In the window for gendata try the following:

gendata 0 localhost 5057
The three command-line parameters specify a ``sleep amount'', a host name, and a port number of the server. The gendata program then collects data to send to the udpserv program. However, it won't send any data until it collects an entire 1KB of input, which means you have to type many lines of data before it will be sent to udpserv -- and this is tedious! Instead, you can use the supply program to generate the input to gendata by the following command:
supply 5 A | gendata 1 localhost 5057
You will see 5KB of data (all A's) sent from the gendata window to the udpserv window, with a one-second pause between each 1KB block of data sent.

The Homework Problem

Describe an experiment that you perform demonstrating how the udpserv3 program receives, in parallel, data from two copies of the supply/gendata programs (you may want to use three windows, one for udpserv3 and the other two for gendata windows). Your experiment should prove that udpserv3 is waiting on two ports at the same time: ideally, the output from udpserv3 will show that it alternately receives data from two different ports from the two different copies of gendata (you may find it useful to vary the sleep times of the two copies to show this).

What to turn in

Explain how you were able to prove that udpserv3 waits on several ports using select. What commands did you use for the gendata copies? You may choose to modify gendata and udpserv3 by adding print statements, but this shouldn't be necessary for the homework assignment. Your explanation doesn't need to include much output from the commands -- submit less than 1KB of text and output in your solution to the homework.

Turning in your answers:

Prepare an email answering the above question. Mail the homework to herman@cs.uiowa.edu and specify in the subject line, the course number, the assignment number and the last four digits of your student ID number (we are hoping that four digits will be unique). So, for example if your student number is 123456789, then the subject line of your email should be:

178 homework 1, student 6789
If you do not have such a subject line, I will bounce your letter back to you and ask for a resubmission of the homework.