CSCI 340: Operating Systems
Fall 2005
Program 2: Socket based chat program
Code due: Midnight Tuesday October 4
(copied to your ecst turn-in directory, see below)
Grading Weight: 2 (programs will have a weight between 1 - 3)

Port assignments (to prevent accidental multiple usage of ports)


Overview:
Implement a server based two person chat program using sockets for communication.

The server should accept the first two connections it receives (call them A and B).  Once it receives two connections, it should take all messages received from process A and send them to process B, and all messages received from process B and send them to process A.


Program Requirements:

The client must accept two command line arguments:  hostname and port 
The server must accept one command line argument:  port
(If you wish, you can use a default hostname and a default port if no arguments are given.)

A client should not read input from the user until the other client is connected.

When ^D is entered at either client, both clients should exit.  Both clients should print a termination statement such as "^D entered, terminating" or "received ^D from other client, terminating."  Since I will be grading these manually, your message can be different.

When both clients exit, the server should wait for two new clients.  The server must handle only one connection (two clients) at any one time.

The chat must be asynchronous.  In other words, clients should not be required to work in lock-step.  For example, if client A sends, it should not have to wait to receive a message from client B before it can send again.

Messages should not be delayed.  For example, if the server was implemented using one process and that process was blocked on a receive from client A, any message from client B would be delayed.

You may print out status messages such as "server connected to client 1" but you may not print out so many status messages (such as those generated by an infinite loop) that the program is not usable.

You may start with someone else's simple client/server application, but you may not start with someone else's chat program.

In order to practice writing multi-process applications, the client must use at least two processes.


Testing Your Program:

I will test your program manually by (1) starting the server (2) starting two clients (3) typing messages in the client windows.  I will also test for graceful termination and the server handling a new connection after the current connection has terminated.


Hints:


Get a simple sockets program working before you start on the chat.  For example, start with Beej's simple client/server program.

You can test the server using telnet.  It is a good idea to get the server working AND TESTED before you start working on the client.  You can specify a port to telnet:  $ telnet tiglon 4211, and then everything you type at the terminal will be send to the server (assuming it is listening on 4211 on tiglon) and everything the sever sends to you will be printed in the terminal window running telnet.

Each client will need two processes:
    1. wait for a message, when a message is received print it to standard out
    2. wait for a line to be typed at the terminal (wait to read from standard input), when a line is typed (return is pressed) read the message and send it
This can (and should) be achieved using a single call to fork().  Since both client processes must exit when it receives a termination message from the server, it is easiest if the parent process is the on that waits for messages.  That way when it receives the termination message, it can call exit() and subsequently kill its child.

The server will need three processes:
    1. listen for connects to the socket, AFTER two clients have connected, fork() a process for each  (Why is it easier to do it after?)
    2. wait for a message from client A, when a message arrives send it to client B
    3. wait for a message from client B, when a message arrives send it to client A
This will require two calls to fork().

In order for both clients to be terminated by a ^D, when a user enters a ^D it's client must send a message to the server and the server must in turn send a message to the other client.

The server is allowed to handle only one connection at a time.  Thus after it forks it two children, it must wait for the children to finish.  This can be achieved using wait() or waitpid().

When compiling on tiglon you may need to specify the nsl and socket libraries:

g++ -g -o server server.cpp -lnsl -lsocket

It is not likely that I will be available to help on Monday October 3rd for help.  It would be a good idea to start this program before October.

General Requirements:
I will test your program using Linux.  You can use jaguar.ecst.csuchico.edu for testing.

If you develop on Cygwin, OSX, or Solaris it should be easy to port to Linux.  If you have trouble porting to Linux, let me know.

You must provide a working makefile.  I will compile your program using the following commands:

$ make server
$ make client

The executables generated by your makefile must be called "server" and "client"


Extra Credit:

15 points extra credit if the client application has a split screen where what one user types is displayed in one half and what the other user types is displayed in the other half.  The goal is to prevent the problem of a message from the other user being printed in the middle of what you are typing.

I suggest you get the basic assignment working first and save a copy before you start working on the extra credit.


How to turn in code:
Turn in all the files necessary to make your program work including a Makefile.  My solution contains the files:

client.cpp
server.cpp
Makefile

copy your files to the turn in directory for this assignment.

See How to turn in assingments for details on turning in assignments.

If you are working with someone, only turn in one copy of the assignment.  It is very helpful is people working together always turn their assignments in under the same name.  Make sure you list both names at the top of all files.



Late assignments:
You will lose 10% for each 24 hours your assignment is late.

e-mail late assignments to me (create a .tar file for all your files and e-mail the .tar file to me)

It may take me much, much longer to grade late assignments (if I have already graded the other assignments, grading late assignments gets a low priority).

I use the time I receive your e-mail, not the time you send your e-mail as the turn in time (sometimes e-mail from an ISP takes a day or two).  If you want to be absolutely sure your assignment gets to me immediately, e-mail it from your ecst account (use your browser (webmail.ecst.csuchico.edu) to e-mail the file to me).