CSC 145/290 Assignment 4: An Improved Chat Program Due Tuesday 10/23/2001 This assignment requires you to use multiple processes and pipes. You are to modify your chat program as follows: * During the authentication stage, after you send the username that you want to talk to to the other side, you should also wait for an acknowledgement byte. The byte is 0 if the other side refused connection (wrong user), and 1 if the other side is indeed the user you want to talk to. This will allow you to restart (as server) gracefully if the other side is not who you want to talk to. For this part, use "select" to timeout your reads. * Once the connection's made with the other side, you are to fork your program into two processes. The new process should be started in its own xterm window. The new process should only read, and display everything it's read. The original process should take keyboard input and write to the other side. That way you don't have to alternate sending/receiving with the other side. You should write another program for the child process (which should be called by execl after the fork). xterm can be give the "-e" option to run a program in a window. Refer to my sample programs. * This assignment also asks you to experiment with pipes. So please write your program in the following manner (humor me): you should establish a pipe between parent and child processes. One end of the pipe should be passed as a command line argument to the child. The first thing the parent should do after the fork is to send through the pipe the *socket* file descriptors that the child will need to communicate with the peer. * In order for your program to terminate gracefully, when you receive the ".signoff.", you should also send ".signoff." to the other side before terminating. This way, both sets of parent/child proecesses will know when they should quit. * (OPTIONAL) Rewrite your program as a daemon on port 30517. When starting your program, you should contact first your LOCAL daemon. The local daemon then communicate with the remote daemon and "negotiate" a connection (you'll have to figure out what "negotiate means"). Assuming you are the first to try to connect, then you should revert to being a server ON THE PORT THAT YOU GOT FROM CONNECT. Make sure you setsockopt the REUSEADDR option so you can bind quickly. You may also still need to delay (use select) your program for a few seconds for the other side to get ready. Please document the exact protocal you decide to implement (this central idea is to free port 30517 once a connection is established). I may also make this a required extension to the assignment. * In the assignment that you hand in, PLEASE HIGHLIGHT WITH A MARKER where you've made the relevant changes with respect to the points above. REMEMBER: the pipe file descriptors must be closed twice each. Once fork is called, a "reference count" on the descriptor is incremented. Your program should print reasonable error messages and have an intuitive interface. ------- Additions: * In order for both parent and child processes to terminate upon receiving .signoff. from the other side, you need to do the following: 1. When the reading processes gets ".signoff." through the socket, it should send through the pipe a signal (which can be anything) to the writing process. 2. In order for the writing process to detect this signal, you need to use select and fd_sets, which I showed you how to do earlier (see sample code on homepage.) That is, the writing process should use select to wait for EITHER keyboard input (file descript 0), or from the its end of the pipe (to the reading process). If select sets the pipe descriptor, that means it got a signal from the child, and so it should read it, send a final .signoff. to the socket, and quit. If you use Linux, make sure you read the select man page carefully. The select statement in Linux changes the timeval structure passed to select! * (Optional) Alternatively, you can figure out how to accomplish the same purpose using Unix signals. Read the text on signal handling.