Assignment 4: Local Chatting
Out on:
February 25, 2008
Due by:
March 5, 2008, 11:00 am (before lecture)
Collaboration:
Pairs
Grading:
Packaging 10%, Style 10%, Performance 10%, Design 10%, Functionality 60%
Overview
The fourth assignment is all about chatting on a local machine shared by multiple users. Not exactly competition to today's instant messaging systems, but we'll get there eventually. :-) Since you are working in pairs again, it's important that you coordinate your schedules and stay in touch during the course of the assignment! Working together in lab or at a laptop in a cafe somewhere is highly encouraged. After the assignment is over, each of you will be asked to evaluate the contribution your partner and yourself made to the assignment.
Scenario
Unix machines are often shared between multiple users. In the good old days, one machine often had lots of users, each logged in over a serial line using a (dumb) terminal. It wasn't unusual for a company to have a box for each department, and all employees in that department shared the machine. Naturally, people always wanted to waste time, and Solitaire wasn't around back then, so people liked to chat with each other; and that's the kind of system you're implementing.
Each machine runs a server process that coordinates the chat between
users on that machine.
The server creates a named FIFO that users can connect to using a
client process.
Consider a server that already has a chat going, among 3 users A,
B, and C say; if user A types a message (i.e. something that is
not a command) and hits return, the client process
sends this message to the server for distribution; the server in
turn sends that message to all of the currently connected clients,
B and C in this case.
If user D starts a chat client, the server announces that event to
all other clients, sending something like "D justed joined the chat!"
to A, B, and C in this case.
If user B leaves the chat using a command like bye, the
server also announces that event to all others, sending something
like "B just left the chat!" to A, C, and D in this case.
The minimum set of commands that clients and servers must support is therefore this: connect/login, say something to all participants, logout/disconnect. Of course there are many more possible commands, for example a command to get a list of all participants in the chat, a command to "whisper" to another user without others seeing the message, a command to "kick" other users (only for administrators), etc. etc. Those are optional and not required, but both servers and clients should be able to "gracefully" ignore commands that they don't understand and do so without leaking information.
Complications
The major complication for this assignment is that all clients and servers that you produce should interoperate without problems, regardless of which team hacked them. So it should be possible to start team A's server on a machine and use team B's, teams C's and team D's clients to log into that server and chat with each other! Obviously you need to discuss a lot of details about the protocol on the discussion list to make this happen; I'd suggest starting that discussion soon!
If you want to facilitate testing, you should probably agree on
which team is using which ugrad machine to host a
server.
Once each team keeps a server running on a certain known box,
other teams can log into that machine, compile their code there,
and see if they can interoperate with the server properly.
It may be a good idea to restart the server regularly using a
cron job, otherwise someone might crash it with
their client and the next team can't test their code because no
server is running.
The final "complication" is that you must use named pipes and nothing else for interprocess communication; let me specifically rule out "morse-code signals" at this juncture. :-)
Problem 0: Protocol Design (20%)
We'll grade your conversations on the mailing list after the assignment is over regarding how effective certain people were in getting the protocol specified and adopted by others. This is a fuzzy grade item, but it's important to learn how to define interface cooperatively, so I'll dare to put it on here.
Problem 1: Chat Server (40%)
We'll grade the server you produce independent from the client (see below). For the server we'll pay close attention to stability and quality of error checking and all those things. You may want to do lots of quality assurance for this one. :-)
Problem 2: Chat Client (40%)
We'll grade the client you produce independent from the server (see above). For the client we'll pay close attention to user interface design and organization. You may want to do lots of usability testing for this one. :-)
Hints
-
The
selectcall will show up in a somewhat unexpected way in the assignment, so please watch out for that. :-) - No, you can't use threads. Not yet. :-) No, you can't use sockets. Not yet. :-)
- It's probably a very good idea to implement some sane kind of debugging output, especially for the server; the easiest way is probably to write to standard error and redirect that into a file when you start the server; remember to append to the log, otherwise you'll probably miss important information regarding why your server crashed on a certain input from a certain client.
- Related to the last point: It may be a good idea to identify each team's code somehow, for example by agreeing on a nickname for each team. That way you can check the log and tell the right time what it sent to crash your server.
- It's possible to encapsulate the protocol inside a module. The module would export a bunch of functions to do certain things and put together properly structured buffers that can be sent through the pipe to the recipient. If you want to go that route, you can freely exchange the relevant code on the mailing list. Just make sure you only define the protocol, not half the server, that would be sharing too much code.
- A command history makes the client more usable. A nice curses TUI makes the client more usable. A lot of other things make the client more usable. :-)
Deliverables
Please turn in a
gzip
compressed
tarball
of your assignment;
the filename should be
cs211-assign-4-login1-login2.tar.gz
with login? replaced by your Unix login names
on ugradx.cs.jhu.edu.
The tarball should contain no derived files whatsoever
(i.e. no executable files),
but allow building all derived files.
Include a README file that briefly explains what your
programs do and contains any other notes you want us to check out
before grading.
We expect that your Makefile handles "the usual" targets
like clean and test aside from all
(which is the main way we will build your program).
Include other "common" files such as INSTALL describing
how to install your tool, CREDITS to pay your respects
to the people whose code you're reusing, and LICENSE
to describe copyright and distribution terms if you feel like it.
You can look at any number of "famous" open source projects to see
what kind of structure is appropriate;
gif2png
is a relatively small example, but you don't need everything in
there.
Aside from your code, what you really need is a README
and a Makefile that works. :-)
Grading
For reference, here is a short explanation of the grading criteria.
Packaging refers to the proper organization of the
stuff you hand in, following the guidelines for Deliverables above.
Style refers to C programming style, including
things like consistent indentation, appropriate identifiers,
useful comments, suitable documentation, etc.
Simple, clean, readable code is what you should be aiming for.
Performance refers to the amount of resources
your program needs to produce the required results; this can
include space, time, and other metrics.
Design refers to proper modularization and the
proper choice of algorithms and data structures; often this can
be judged by asking "How hard would it be to add feature X?"
and "How hard is it to replace algorithm X with algorithm Y?".
Functionality refers to your programs being
able to do what they should according to the specification
given above; if the specification is ambiguous and you had
to make a certain choice, defend that choice in your
README file; if the specification is too general
and you had to add certain restrictions, defend those in your
README file as well.
If your programs cannot be built on ugradx.cs.jhu.edu
you will get no points whatsoever.
If your programs cannot be built without warnings using
gcc -ansi -pedantic -Wall -Wextra -std=c99 -O
we will take off 10% (except if you document a very good reason).
If your programs cannot be built using make we will
take off 10%.
If your programs fail miserably even once,
i.e. terminate with an exception of any kind or dump core,
we will take off 10%.
Finally, make sure to include your name and email address in
every file you turn in!