Now we're going to turn jtalk into a threaded program. And we're going to beef the server up.
First, look in the lab directory (/blugreen/homes/plank/cs360/labs/lab9/). There are two programs there. The first is jtalk.c. This is going to be the client for your jtalk. It requires a host and port number on the command line. It first asks for a user name, and then requests a connection to the socket at the host/port number. Once the connection is made, a separate thread is forked off. The The main thread reads lines from standard input, prepends the name to them and sends then to the server using send_string. You'll note that what send_string does is send the length of the string, and then the string itself. This makes it easy for the server to parse its input without having to look for newlines.
The other thread (from_socket()) reads strings from the socket and prints them to standard output. It uses read_string() to do this. As you might guess, read_string() reads the length of a string and then the string itself.
If either the socket or standard input is closed, then jtalk exits.
Ok, now look at cat_server.c. This is a simple program that serves a socket, and then once it gets a connection, it simply shuttles all input from the connection back to the connection. You can test out jtalk by running cat_server on one machine, and then connecting to it with jtalk. Anything that you type in the jtalk window should come back with the name prepended to it. Make sure you understand everything about jtalk and cat_server before going on.
Threads really make your life easier here. You should have one thread that calls accept_connection(), and whenever it gets a connection, it forks another thread that services that connection. Obviously, you'll need some data structure that is shared by all threads so that any thread may write to all of the connections.
Note that you will need a mutex here protecting that data structure. This is because one thread may be writing to all the connections, and another thread may exit simultaneously. Think about it. Also think about what you need to do with sigpipe.
Finally, you should have an extra thread that runs the ``jtalk console''. This thread prints a prompt to standard output, and then accepts commands on standard input. It really only accepts three commands:
I never call pthread_join(), but I do call pthread_exit() when a connection goes away. Remember to close the file descriptor too.
Use ctime() to print times.
You will have to modify send_string() etc to deal with disconnecting correctly. However, you cannot change jtalk -- your server must work with the jtalk that I have provided.
You may assume that if you catch SIGPIPE on a socket, that any read() calls on that socket will return instantly with a value of zero. This makes life much simpler if you structure things well.
As usual, work in increments, and test incrementally.