CS 3733 Operating Systems, Spring 1996 Assignment 5

Read the entire assignment before starting. Be prepared to demonstrate your programs at the beginning of class on the due date.

Part I

Write a UICI server which will accept a transmission and save the result in an array. It should read from the network in 1024-byte blocks. Use a buffer of size MAXSIZE to receive the data. After it receives the transmission (the sender client has closed the connection) the server will output the received information to the /dev/audio device in 1024-byte blocks. The audio device should then be closed and the program should exit. If more data us received than will fit in the buffer of size MAXSIZE, the server should print an appropriate error message and ignore the rest of the incoming data.

Write a UICI client which will take input from standard input, and send it to the remote UICI server. When an end-of-file is encountered, the client terminates.

Call your server program server1.c. It should take one command line argument which is the port number. Call your client program clientin.c. It should take two command line arguments, the name of the remote server and the port number.

Have your server program display the number of bytes received so far when it receives a SIGUSR1 signal, and the number of bytes sent so far when it receives a SIGUSR2 signal. Use a value of 1024*8*16 for MAXSIZE during testing. This allows for 16 seconds of audio. Test your client program by redirecting standard input from /dev/audio.

You can start with the programs B.2, B.3, and B.4 from Appendix B. B.1 contains the uici.h header file. Little, if any, modification will need to be made to the client program and only a small modification to the server is required. The uici implementation should not be modified. These files are available in /usr/local/courses/cs3733/pup/apB.tar. This also contains a makefile. Start by compiling these programs and making sure the client can send to the server.

Students will be assigned ranges of port numbers to use so that there is no conflict.

Turn in copies of any modified source code and describe what happened when you tested your programs.

Part II

Copy your server1.c file to server2.c. Modify it so that after it receives a transmission it does not send it to /dev/audio. Instead, it waits for another connection and sends the data on this new communication channel. Use a port number which is one greater than the port number used for receiving the data. After finishing the transmission if closes the communication channel and exits. After your program seems to be working correctly, modify MAXSIZE so that you can receive a one-minute transmission.

Copy your clientin.c file to clientout.c. Modify it so that instead of sending data it receives data from the communication channel and sends to to the /dev/audio device. After it receives all of the data it should close the audio device and exit.

Turn in copies of any modified source code and describe what happened when you tested your programs.

Part III

Copy your server2.c file to server3.c. Modify it so that after it receives a transmission, it can receive connections from several clients simultaneously. Do this by having the server listen for connections in a loop and when a connection is made, fork a child to handle the communication. The child will exit when the communication is complete. Once it gets to this stage, the original parent will only exit upon receiving a CTRL-C.

Turn in copies of any modified source code and describe what happened when you tested your programs.

Part IV --- Extra Credit

Only attempt this if you have the other parts working well.

One problem with the implementation of PART III is that each child gets its own copy of the audio buffer. Since this can be quite large (a half-megabyte per minute) it would be better if this could be shared. One method would be to store the audio in a file and have each of the children open that file. Instead, modify your server3.c program (call it server4.c) so that the audio buffer is kept in shared memory. Shared memory segments are controlled much like semaphores. See Section 8.9.1 of PUP and the man pages. Since the shared memory segment will be used only by children of the parent, you can use IPC_PRIVATE for the first argument to shmget. The shared memory segment should be removed by your program when it is no longer needed. You can use

to see what shared memory segments are being used and
to delete shared memory segments.