Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: THEend8_
School of Information Technology and Electrical Engineering
CSSE2310/CSSE7231
Assignment 1 Marks: 75 (for CSSE2310), 85 (for CSSE7231)
Weighting: 15%
Due: 3:59pm 7 May, 2021
Introduction
The goal of this assignment is to test and demonstrate your knowledge of Unix multiprocessing and inter-process
communication using processes and pipes, and to further strengthen your general C programming capabilities
through more advanced program design and implementation.
You are to create a set of programs, one server (server) and two clients (client, clientbot), which together
form a simple chat messaging system. The server is responsible for running the clients as specified in a chat
configuration file, and establishing pairs of pipes such that each client can communicate bidrectionally with the
server. The clients and server will communicate using a simple text-based messaging protocol. client is a
simple client that takes its commands and chat messages from a text file, while clientbot has slightly more
advanced functionality, and listens to the chat stream and makes “canned” responses based on messages sent
by other users.
Student conduct
This is an individual assignment. You should feel free to discuss general aspects of C programming and
the assignment specification with fellow students, including on the discussion forum. In general, questions like
“How should the program behave if 〈this happens〉?” would be safe, if they are seeking clarification on the
specification.
You must not actively help (or seek help from) other students or other people with the actual design and
coding of your assignment solution. It is cheating to look at another student’s assignment code and
it is cheating to allow your code to be seen or shared in printed or electronic form by others.
All submitted code will be subject to automated checks for plagiarism and collusion. If we detect plagiarism
or collusion, formal misconduct proceedings will be initiated against you, and those you cheated with. That’s
right, if you share your code with a friend, even inadvertently, then both of you are in trouble. Do not post
your code to a public place such as the course discussion forum or a public code repository, and do not allow
others to access your computer - you must keep your code secure.
Uploading or otherwise providing the assignment specification to a third party including online tutorial and
contract cheating websites is considered misconduct. The university is aware of these sites and they cooperate
with us in misconduct investigations.
You may use code provided to you by the CSSE2310/CSSE7231 teaching staff in this current semester
and you may use code examples that are found in man pages on moss. If you do so, you must add a comment in
your code (adjacent to that code) that references the source of the code. If you use code from other sources then
this is either misconduct (if you don’t reference the code) or code without academic merit (if you do reference
the code). Code without academic merit will be removed from your assignment prior to marking (which may
cause compilation to fail) but this will not be considered misconduct.
The course coordinator reserves the right to conduct interviews with students about their
submissions, for the purposes of establishing genuine authorship. If you write your own code,
you have nothing to fear from this process.
In short - Don’t risk it! If you’re having trouble, seek help early from a member of the teaching staff.
Don’t be tempted to copy another student’s code or to use an online cheating service.
Specification
Server
Command Line Arguments
Your program (server) is to accept command line arguments as follows:
./server configfile
where configfile is the name of a text file that describes the clients participating in the chat session.
The format of the config file is as follows:
• Lines where the first non-whitespace character is a # are to be ignored as comments
• All other lines are of the form
program :arg
where program is the path to the program to be run as the chat client, and arg is a single command
line argument that will be passed to program when it is executed. These two fields are separated by a
colon ‘:’. A colon may not appear in either the program or the argument, however other characters such
as directory slashes, spaces etc are valid.
The server will attempt to create a chat session with one participant per line in the config file. The following
shows a sample config file.
# Chatter 1 is ./client, started with chat1.txt as its argument
./client:chat1.txt
./clientbot:botconf.txt
# Another comment, ignored
./client:chat2.txt
Listing 1: Sample server config file
This config would specify a chat session with three participants, the first running ./client, the second
./clientbot, and the third ./client. Note that these may include include leading directory specifiers (e.g.
./, ../, or absolute paths). These should be passed directly to exec() when attempting to start the clients -
you are not required to test for the validity or existence of these files prior to attempting to execute them. Note
that in this chat session, the same program client is run twice, but with a different command line argument.
General notes on required server functionality:
• Your server will fork() and exec() a new process/program for each client, according to the chat config
• Your server must establish communications with each child using pipes and the pipe() system call. Note
that communications are required in both directions, so two pipes will be required for each client.
• Your server is to support an arbitrary number of clients (up to system limits of maximum processes, file
handles etc). A session with a single client is also valid, if somewhat lonely.
• If the specified chat config file is missing, or the server command line is malformed, the server shall emit
an error message to stderr and exit with the appropriate exit code specified in Table 1.
• The second argument on each line in the server config is passed unmodified as the command line to the
respective client upon startup.
• The server will need to track the expected state of each client independently, and communicate using the
protocol described in Table 3, ensuring the correct messages are sent according to the client state.
• The server should learn the names of all clients before sending any ”YT:”s
• After a server sends a client YT: they should only read from that client until it receives ”DONE:” or
”QUIT:” back from that client
• The server must suppress any client output to stderr (see the Hints section at the end of this document).
• As clients quit or are kicked, the server must track this and no longer attempt to communicate with
terminated clients.
• If a poorly formatted message or eof is received from a client, treat it as if they quit
6959462-30065-6649710
• If all clients have left the chat, the server should terminate with exit code 0.
• The server should expect no input on stdin
• The server should emit to stdout
– a log of clients entering the chat (a NAME: message was accepted and verified unique)
(name has entered the chat)
– all messages sent by all clients (CHAT:
(name ) message contents (note space between (name ) and the message text
– a log of clients leaving the chat
(name has left the chat)
• The server should emit nothing to stderr except as specified in Table 1.
The following shows an example stdout captured from a server session.
(client has entered the chat)
(client0 has entered the chat)
(clientbot has entered the chat)
(client) Hey everyone I'm fred
(client0) Hey where did all the dinosaurs go?
(client0) I miss them!
(client) Asteroid got'em - boom!
(client0) Can I get a coffee?
(clientbot) Yes please, make mine a double shot
(client has left the chat)
(client0) I'm still here
...
Listing 2: Sample server stdout output
Clients
This section first describes the general behaviour of client programs, before further defining the specific behaviour
of each of client and clientbot.
In general, clients are programs that receive messages over stdin, and send their responses over stdout.
Clients also generate output to stderr. This stderr output will be ignored by the server, however client stderr
output will be used to test the functionality of your clients as standalone programs.
Clients must be able to respond to a specific set of messages from the server (see Table 3) for message format
specifics and examples):
• WHO: - a query from the server asking the client to identify itself. Client respondes with NAME: message
• NAME_TAKEN: - server is indicating that name is already taken, and will ask again (with WHO: next time
around.
• YT: - ”Your turn” - the client is now free to send CHAT: messages to say things into the chat
• MSG: - the named client sent a message to the chat. Note that clients will receive their own messages back
via this channel.
• KICK: - the client has been kicked from the server. It should immediately send a QUIT: message to the
server and then terminate.
• LEFT: - the named client has left the chat
Clients are permitted to send the following messages (at the appropriate time):
• NAME: - tell the server the name we want to use (only in response to a WHO: message)
• CHAT: - say something into the chat (only after receiving YT:)
• DONE: - inform the server that we are done talking for now, let somebody else have a turn (only after
receiving YT:)
• KICK: - request to kick the specified client
6959462-30065-6649710
• QUIT: - tell the server we are leaving
When the client receives the MSG:name :message command from the server it shall output the message to
stderr as follows (note space between the sender name and their message):
(sender ) message
When the client receives the LEFT: command from the server the client will emit to its stderr the following
(name has left the chat)
Below is an example of the stderr output from a typical client interaction. Note that it’s format and
contents are identical to the server’s stdout, except that no messages are printed when clients enter the chat.
(client) Hey everyone I'm fred
(client0) Hey where did all the dinosaurs go?
(client0) I miss them!
(client) Asteroid got'em - boom!
(client0) Can I get a coffee?
(clientbot) Yes please, make mine a double shot
(client has left the chat)
...
Listing 3: Sample client stderr output
Each client has a hard-coded name – client and clientbot as appropriate (see below). However, the server
requires each name be unique, and will reply with a NAME_TAKEN: message if somebody is already using that
name. In that case, clients are to append an integer, starting from zero, to their name and use this in their
response to the next WHO: message received from the server. Each client will repeat this with an increasing
integer until the server is satisfied that their name is unique (e.g. client, client0, client1, . . . )
A client shall terminate in the following conditions. The exit codes and required output for these different
cases are specified in Table 2:
• After sending a QUIT: message (this is a normal exit).
• Upon reaching the end of its chat script. Do not send a QUIT: message, just terminate immediately (this
is a normal exit).
• Upon receiving a KICK: message. Do not send a QUIT: message, just terminate immediately (this is a
kicked exit).
• If it receives an invalid command from the server, or any other sort of error such as end of file on stdin
(these are considered communications errors)
client
This is the simplest client. It is launched with the following command line:
./client chatscript where chatscript is a simple text file that contains the messages that the client
will send, and other simple actions the client can take.
If the client is run with an invalid number of arguments, or the specified chat script file does not exist,
client should exit with the appropriate error message to stderr and exit code as specified in Table 2.
After the initial WHO:/NAME: negotiation, the client can simply emit the commands that are specified in the
chat script.
An example chat script is shown below:
CHAT:Hello everybody!
DONE:
CHAT:How are you doing today?
CHAT:I'm a pretty stupid client, but that's ok
DONE:
CHAT:I'm still talking, how about that?
DONE:
QUIT:
Listing 4: Sample client chat script file
6959462-30065-6649710
Note the following about the chat script format:
• Messages to be sent to other chat clients start with CHAT:
• Sets of messages are terminated with DONE:
• The QUIT: command informs the server that this client is leaving the chat.
• The colon (‘:’) character must not appear in the body of any messages. We will not test this case and
you don’t have to handle it.
clientbot
The clientbot uses the same communication protocol and server interactions as the regular client, however
instead of responding from a pre-written chat script, it listens for messages (stimulus) from other clients and
auto-replies a response upon receiving certain messages.
clientbot is launched as follows:
./clientbot responsefile
where responsefile is a text file that contains the list of stimulus and response pairs, each seperated by a
colon character. Similar to other configuration files in this assignment, lines in which the first non-whitespace
character is a # are to be treated as comments.
Lines of the form
:
specify the stimulus string to be looked for and the corresponding respond to be made.
Neither the stimulus nor the response may contain the colon character – we will not test for this and you
do not have to handle this case.
For example, the following config
# 2014 called, they want their meme back
F in the chat:F
# allright allright allright allright
What's cooler than being cool?:ICE COLD!
# This message brought to you by Big Coffee
coffee:Yes please, make mine a double shot
Listing 5: Sample clientbot configuration file
would cause the clientbot to listen to the chat messages from other clients, match each message against the
entries in the stimulus file, and if detected reply with the required response.
Stimulus messages are to be matched in a case-insensitive manner – from the previous example listing, a
message containing “COFFEE” in uppercase would match. The stimulus string must appear somewhere in the
incoming chat message to be matched, but it does not have to match the entire message.
If the provided responsefile is missing or invalid in any way, the clientbot should exit immediately,
returning the appropriate error code (see Table 2).
The clientbot must not reply to its own messages, but it might respond to messages from other
clientbot instances participating in the chat.
To operate correctly, clientbot must somehow remember the messages it’s seen and save them until it
next receives YT: from the server indicating it’s time to reply. Don’t try to cheat and immediately emit CHAT:
messages when you get matching stimulus!
Error messages and exit codes
Server
Exit Condition Message (to stderr)
0 Normal exit
1 Incorrect number of args or unable to open configfile Usage: server configfile
. . .
Table 1: Server errors, messages and exit codes
6959462-30065-6649710
clients
Exit Condition Message (to stderr)
0 Normal exit
1 Incorrect number of args or unable to open chatscript (client) Usage: client chatscript
1 Incorrect number of args or unable to open responsefile (clientbot) Usage: clientbot responsefile
2 Communications error Communications error
3 Client was kicked Kicked
. . .
Table 2: Client errors, messages and exit codes
Client/server interactions
Upon starting, the server will read the chat config to identify the clients who are participating in the chat
session. The server communicates with each client in a round-robin fashion, in order of the clients’ appearance
in the chat config file.
The server begins by sending the WHO: message to each client, and listening for a NAME: response back.
The server checks the received name against any other named clients. If the name already exists the server
should send a NAME_TAKEN: message to that client, then move onto the next client. Next time around it will
re-send the WHO: message to clients that still haven’t completed name negotiation. Note that this implies it is
possible for a client to never complete name negotation, but other succesfully named clients can still be chatting.
(server)WHO:
(client)NAME:name
(server)YT:
(client)CHAT:
(may repeat)
(client):DONE:
...
(client)QUIT:
Listing 6: Sample communications
Message protocol
Messages between the clients and the server take the the form
CMD:arg1:arg2:...
where CMD is an uppercase command word, and arg1 .. argN are arbitrary text parameters to the command.
These arguments, and the command word, will not contain a colon character. Different commands have different
number of arguments - see the later tables for details.
Messages are sent in text over pipes established by the server.
The following table describes the messages sent between the server and clients. Note that broadcast messages
(i.e. messages to all) are sent to all clients participating in the chat session.
6959462-30065-6649710
Direction Format Detail
server → client WHO: Receiving client should reply with its name (NAME:
message)
server → client NAME_TAKEN: Somebody is already using that name (server will
follow up with another WHO: message)
server → client YT: Receiving client is free to send messages
server → client KICK: The receiving client is being kicked from the chat –
they must terminate immediately with the appropri-
ate error code
server → all MSG:name :text Server is broadcasting that the client called name
sent message text
e.g. MSG:fred:Hello world!
server → all LEFT:name The named client has left the chat
e.g. LEFT:client
client → server NAME:name Client informing the server of their name
e.g. NAME:Fred
client → server CHAT:msg Client sends a chat message
e.g. CHAT:Can I get an F in the chat?
client → server KICK:name Ask the server to kick the named client out of the
chat. The server will generate a KICK message to the
relevant client, if they are in the chat.
client → server DONE: Client is informing the server that it’s done sending
messages for now. The server will follow up with an-
other YT: message when it’s this client’s turn again.
client → server QUIT: Client is informing the server that it’s leaving the
chat.
Table 3: Client / server communication protocol
Style
You must follow version 2.0.4 of the CSSE2310/CSSE7231 C programming style guide available on the course
BlackBoard site.
Hints
1. Consider starting with client.
2. You can test and develop your client programs standalone – just interact with them over stdin/stdout
as though you are the server.
3. Be careful to flush output streams, don’t make any assumptions about the default flushing behaviour of
pipe()-created file handles.
4. Do some experiments to understand how to establish pipes in both directions between a parent and its
fork()/ exec() child. Make sure you know how to do this before starting on the server.
5. Think about the various states a client can be in as it progresses through a chat session, and the mes-
sages/responses it is expecting in each state. Getting this right will greatly simplify your client and server
programs.
6. When debugging client/server interactions, the tee command may be useful. You can wrap your client in
a shell script that uses tee to pass through and log stdin/stdout, and launch the wrapper script from
the server (in the chat config). This will allow you to log the interactions between the two.