An instant messaging (or chat) system allows multiple clients to exchange messages in an interactive fashion. Lines of information are typed at one client and then appear in the output window of all the other clients connected to the same chat room.
In this project, you will build a system that consists of a centralized IM server and that allows two client applications to connect with the server and exchange the message dialog between the clients. Note that the IM server will be one application and the IM client will be a separate application (with two instances when the system is up and running).
The server should run until one client closes its connection. When this happens, all 3 processes should exit gracefully, closing their sockets. Your client program should accept two parameters on the command line: the host on which the server is running and the port to be used for establishing a connection. The host may be specified as a textual hostname (which may or may not be fully qualified), or a dotted quad IP address.
user: A human that communicates with the system through a client program. Each user has an identifier (nickname) that identifies the user to other users. You decide what constitutes a user identifier and whether is can be set/changed by a user.
user interface: The text interface supported by the client. This is how the user interacts with the system. You should start by planning on a very minimal user interface. A "good" interface would provide some separate window or dialog in which the user types the lines that will be transmitted through the server to the other client, and a separate window for output, which would include the lines sent and the lines received. A less ideal interface would do both within a single window.
application protocol: The definition of the communication that takes place between the client and the server. There are two parts to defining an application protocol, and for this project, both can be very simple. The first part is the format of the messages exchanged between client and server. Given only two clients and the lack of a requirement for other functional control between the client and server, this can be just the text typed by the user, terminated with a newline. Adding other functions, such as setting a nickname, could require more definition of the format. The second part is the semantics. What is done when messages of particular format arrive? What order are operations carried out in?
message: In this context, message refers to the text message typed by the user and sent from one user to another. You may decide if a message is exactly one line of may be multi-line with some user interface method of submitting a multi-line message. With respect to the user interface, each message should be labeled with the identifier (nickname) of the user who sent it.
I would like you to approach the development of this project in stages. Almost no work will be wasted with this approach and it will allow you to focus concerns on just a few new concepts in each stage instead of having to think about many new things at once. In addition, grading for this project will be on a corresponding tiered scale, with up to 80% of the grade being attainable by a great realization of stage 1, 90% of the grade attainable for stage 2, and the final 10% being reserved for stage 3.
In stage 1, we constrain the application protocol to enforce a strictly alternating message exchange. The server decides which client goes first and communicates that decision to both clients; call the chosen client c1. Client c1 types a message and terminates the message. The message is relayed to the other client, called c2. Client c2 sees the message from c1 and then types their own message. This is sent to c1 and displayed on their output. This process repeats.
Stage 1 of the development allows us to focus on the sockets API and to implement some fairly straightforward servers and clients. By constraining the application protocol to the "ping-pong" message exchange, we allow both the clients and the server to ignore the complexity involved in concurrent I/O. Each can use blocking reads/recv's on a single file descriptor at time.
The stage 1 version, with its single I/O, degrades the user experience of the instant messaging system significantly. If we look at AIM or IRC, a user on client c1 could compose and send multiple messages before getting a response from the user on client c2. Both could also be composing and sending messages concurrently as well.
The goal of stage 2 is to address this defecit. To solve this problem involves enhancing both the server and the clients so that they can handle more than one outstanding I/O operation at a time. There are multiple ways to try and achieve multiple I/O concurrency under Unix, and you are welcome to be creative in finding your solution. I caution you to try and not make it more complicated than it has to be. Please do not discuss your solution to the concurrent I/O problem with your classmates, as I want everyone to think through their own solution. Your solution may not employ busy waiting/polling.
By the end of stage 2, we have a fairly functional instant messaging system, but it lacks many of the features that would make it first class. This stage is open-ended in that you are encouraged to add whatever features you like. Some of the more obvious include:
True multiple windows at the client, separating output and input. This is almost expected for an excellent implementation of Stage 2, and, by itself, is not sufficient for the entire 10% available in this stage.
Enhancing the application protocol to allow the user to set and change the nickname.
Allowing more than two clients.
Supporting more than just a single chat room.
Other enhancements to the application protocol, possibly including "richer" exchanges like a picto-chat on a Nintendo DS might allow.
Whatever else you want to dream up.
Note that, even if you enhance the application protocol and give it more structure, we (for now) can continue to assume a homogeneous set of computers. In particular, this means that we can ignore byte-ordering issues.