HW3_Wet

advertisement
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
Homework Wet 3
Due date:
Thursday, 2.1.2014, 12:30 noon
Teaching assistant in charge:
Arie Tal
Important:
the Q&A for the exercise will take place at a public forum Piazza only. Please note,
the forum is a part of the exercise. Important clarifications/corrections will also be published in
the FAQ on the site. A number of guidelines to use the forum:
 Read previous Q&A carefully before asking the question; repeated questions will probably
go without answers
 Be polite, remember that course staff does this as a service for the students
 You’re not allowed to post any kind of solution and/or source code in the forum as a hint
for other students; In case you feel that you have to discuss such a matter, please come to
the reception hour
 When posting questions regarding hw3, put them in the hw3 folder
Note: Start working on the assignment as soon as possible!!! This assignment involves
algorithmic design, a lot of code writing, and extensive testing and debugging. This time, for
sure, there will be no postponement.
1 General Description
A small company's Information Technology (IT) team decided to roll their own internal on-line
group chat service. Their intent was that any employee in the company could join the chat service,
receive messages posted by other employees and post their own messages.
When the IT team presented their project proposal to management, management agreed to fund
the project, provided that additional features were added to it. Namely, management wanted to
add the capability of sending private messages between users, and the capability of querying who
is currently connected to the system, as well as an indication whenever anyone joins or leaves the
chat service.
After the IT team went through a few use-case scenarios, they deemed it necessary to also enable
anyone joining the chat service to query the recent history of messages, instead of starting a
series of questions in an attempt to catch up with the current discussion. It was decided that a
history of the last 100 messages should suffice. It was also agreed that private messages would
not be included in the history.
1
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
2 Detailed Description
The chat service is composed of two components:
1. A central chat service server that listens to client connections, messages and queries, and
broadcasts messages to clients.
2. A client that allows each employee to connect to the chat service. Each employee runs its
own copy of the client component.
Communication Protocol Description
All communication between clients and the server must be done through named pipes (FIFOs).
You must use the following naming convention for the FIFOs:

“server-fifo” – the FIFO that clients use to register themselves with the server. The FIFO
is created and managed by the server. A single FIFO is used for all clients to start the
registration process.

“fifo-<client-pid>-out” - the name of the FIFO used for messages from the client to the
server, where <client-pid> is the process id of the client.

“fifo-<client-pid>-in” - the name of the FIFO used for messages from the server to the
client
fifo-1234-in
fifo-1234-out
Chat
Service
client1
server-fifo
fifo-5678-in
fifo-5678-out
client2
Each message sent though the FIFOs (except for server-fifo, see below) is composed of:
message length – 4 bytes
message – a character string of length message length
Note: The message-length is in the binary representation of an int type, not a string. Also note
that message is a string that is not null terminated.
2
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
Establishing a client-name
When a client is run, the first argument is its client-name. For example,
$ ./client client1
the client-name for the client above will be “client1”. The client-name can be any string that does
not contain spaces.
If no client-name parameter is supplied, the client will use “pid:<client-pid>” for its client-name,
where <client-pid> is the client’s process id.
Client-Server Initial Connection Protocol
Upon server startup, the server must
1. Print the message
Starting the chat service
2. Create the “server-fifo” FIFO and start listening for client requests
The client connects to the server using the following protocol:
1. The client creates the two FIFOs fifo-<client-pid>-in, and fifo-<client-pid>-out, where
<client-pid> is the client process id.
2. The client sends a single message on the server-fifo that contains its client-pid and
client-name in the following format:
message length – 4 bytes, the length of the client-name string
client-pid – 4 bytes, in binary representation of an int type
message – a character string of length message length containing the client-name
3. If there is no other client connected to the server using the same client-name, the server
sends a "/ack" command to the client using the FIFO fifo-<client-pid>-in, and the
connection proceeds (read below about the "/inuse" command).
4. If the connection is accepted by the server, all currently connected clients, including the
joining one, must see a message:
<client-name> joined the chat
5. Any subsequent communication between the client and server is done through the two
FIFOs fifo-<client-pid>-in, and fifo-<client-pid>-out.
3
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
Notes:
1. If the server is not running when the client starts, the client must print a message
The chat service is not available
and terminate with an exit code of -1.
2. If another client with the same client-name is connected to the server, the connection will
be rejected. The server must send a “/inuse” command back to the connecting client
through the FIFO fifo-<client-pid>-in (see the section on "Commands” below), and the
client must only print a message
Client-name <client-name> in use
and terminate with an exit code of -2. Replace “<client-name>” in the message with the
requested client name.
Client-Server Connection Termination Protocol
Upon client termination due to a “/leave” command (see section on "Commands” below), end-ofinput, or SIGINT (ctrl-C),:
1. The client must send a “/leave” command to the server.
2. The server must send a "/leave_ack" command back to the originating client (and only
the originating client).
3. The client must shut down gracefully, and remove the FIFOs.
4. All remaining connected clients must print a message:
<client-name> left the chat
Upon server termination due to SIGINT (ctrl-C):
1. The server must send a “/stopped” command to all connected clients.
2. All connected clients must print the message
The chat service was stopped
and exit gracefully with an exit code of 0 (cleaning up FIFOs, etc.).
3. The server must shut down gracefully, and remove the “server-fifo” FIFO.
Note: Use signal(SIGNUM, <signal-handler-routine>) to replace the a default signal
handler with your own. For more information regarding the signal library routine, see the man
pages.
4
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
Messaging-Protocol
Public messages:
When a client sends a regular message, not a recognized "command” (see section on “Commands”
below), the message should appear on all connected clients in the following format:
<client-name>: <message content>
Messages must be printed on the client as soon as they arrive. The client must not wait for any
user input before printing incoming messages.
A client sends a regular message by typing it and pressing Enter:
<message content>↵
Note: Incoming messages from other users must be printed even while a user is typing their
messages.
Private messages:
A client can message another client privately by mentioning the receiver's client-name at the
beginning of the message as follows:
@<receiver-client-name> <message content>
A received private message will have the following format:
<sender-client-name>: @<receiver-client-name> <message content>
No other client except for the sender and the receiver shall print the message.
If a client with the <receiver-client-name> is not currently connected, the client <senderclient-name> must print the message
<receiver-client-name> is not connected
Client Recognized Commands:
/leave - notify server (by a client) of communication termination due to client leaving the chat
service.
/history - a client uses this command to ask the server for a history of the last 100 public
messages (the /history command ignores private messages). The history of messages must be
sent only to the asking client. The history is formatted as follows:
5
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
history: <client-name>: message
history: <client-name>: message
….
Note: /history may also print "<client-name> joined the chat" and "<client-name> left the chat"
messages.
“/who” - a client uses this command to get a list of clients that are currently connected to the
server. The list of currently connected users must be sent only the asking client. The list of
currently connected users is formatted as follows:
who: <client-name-1>
who: <client-name-2>
…
Server-side prints:
When a chat server starts, it should print the message
Starting the chat service
When a client with client id <client-name> connects to the server, the server should print
Connected to client <client-name>
When a client with client name <client-name> disconnects from the server, the server should
print
Disconnected from client <client-name>
When the server shuts down (when it is stopped, i.e. by pressing ctrl-C or sending it a SIGINT), it
should print the message
Stopping the chat service
6
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
An example output from three clients connected to a chat server:
$ ./client Alice
Connected
Alice joined the chat
This is a message by Alice
Alice: This is a message by Alice
Jane joined the chat
Jane: This is a message by Jane
Bob joined the chat
$ ./client Jane
Connected
Jane joined the chat
/who
who: Alice
who: Jane
This is a message by Jane
Jane: This is a message by Jane
Bob joined the chat
$ ./client Bob
Connected
Bob joined the chat
/history
history: Alice joined the chat
history: Alice: This is a message by Alice
history: Jane joined the chat
history: Jane: This is a message by Jane
history: Bob joined the chat
$ ./server
Starting the
Connected to
Connected to
Connected to
chat service
client Alice
client Jane
client Bob
7
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
3 Remarks
1. You should aim for maximum parallelism. Points will be deducted for “serialized”
communications between clients. For example, if client A sends a private message to client B,
and client C sends a private message to client D, the two should not interfere with oneanother.

Hint: You should allow multiple threads to scan the list of active connections in
parallel.
2. There is no requirement for messages to be printed at the exact same order in every client.
However, public messages from the same client must be printed in the same order in all the
connected clients. Private messages from client A to client B must be printed in client B in
the order they were entered in client A.
3. For the history management, you could use either a server-side data structure, or a special
history-manager “client” (that runs inside or alongside the server), or a different approach.
Whichever one you choose, document the reason you chose it, and how it affects parallelism.
4. Make sure the client and server do not run into a deadlock. Points will be deducted for any
deadlocks.
5. Make sure the client and server handle graceful shutdowns. Points will be deducted for
segmentation violations, SIGPIPEs, crashes, etc.

Make sure there are no lingering files or FIFOs after the server and clients shut down.

Make sure that all clients disconnect gracefully when the server is shutdown, and that
the server is aware of any client disconnecting (for any reason).

Make sure that clients erase their FIFOs when they shutdown or are stopped via ctrl-C.

If the client gets killed by a signal other than a SIGINT (e.g. when the window closes, or
kill -9), the server should gracefully handle the situation as a regular client disconnect.
In that case, it is permitted to have lingering FIFOs. Upon restarting the client with the
same client-name, it must be able to connect smoothly (i.e. without being rejected by
the server).
6. Avoid printing anything other than what was explicitly specified in the protocol above. Your
server and client programs must implement the protocol above to the letter. If we can’t test
your code with our automated testing tools, you will lose points.
7. You can add more commands between the client and server for debugging purposes, as long
as they do not interfere with the implementation of the communication protocol.
8. You can assume a maximum message length of 10K.
9. Your code should build and run cleanly on the RedHat 8 Linux VM. However, you should not
assume a single-core machine, and should therefore test your code on t2 (or an equivalent
multi-core machine) as well.
10. Please stress-test your code. That means running your server with many client instances
in different scenarios, sending hundreds of messages to one another. We will!
8
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
4 Submission

You should electronically submit a zip file that contains the source files and the Makefile.
Its name should be “Makefile”. The Makefile will create two executables named “server”
and “client”.

You should submit a printed detailed design of your program, including explanations on
the chosen algorithms, synchronization mechanisms, etc.
 You should also submit a printed version of the source code. Document your source code!
 A file named submitters.txt which includes the ID, name and email of the participating
students. The following format should be used:
Bill Gates bill@t2.technion.ac.il 123456789
Linus Torvalds linus@gmail.com 234567890
Steve Jobs jobs@os_is_best.com 345678901
Important Note: Make the outlined zip structure exactly. In particular, the zip should
contain only the following files (no subdirectories):
zipfile -+
|
+- all your source/header files
|
+- Makefile
|
+- submitters.txt
|
+- documentation.pdf
Good Luck!
The Course Staff
9
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
Appendix
Summary of Client Commands:
Command
Description
/leave
Client is leaving the chat service, and disconnecting from the server.
/history
Client asks for a history of the latest (up to 100) public messages.
/who
Client asks for a list of the currently connect clients (list of client-names).
Summary of server commands
Command
Description
/ack
Server approved client registration, communication may proceed.
/inuse
Server rejected client registration. Detected an attempt to register with a clientname that is currently in use by another connected client.
/leave_ack Server acknowledges a client's /leave command, and disconnects from the client.
/stopped
Server is shutting down. Client must gracefully disconnect and cleanup FIFOs.
Summary of Client-side Messages:
Message
<client-name> joined the chat
The chat service is not available
Client-name <client-name> in use
<client-name> left the chat
The chat service was stopped
<client-name>: <message content>
<sender-client-name>: @<receiver-client-name> <message content>
<receiver-client-name> is not connected
history: <client-name>: message
who: <client-name>
Summary of Server-side Messages:
Message
Starting the chat service
Connected to client <client-name>
Disconnected from client <client-name>
Stopping the chat service
10
Operating Systems (234123) – Winter-2013/14
(Homework Wet 3)
A few useful tips:
For stress-testing, it would be beneficial for you to create additional tools and scripts for running
multiple clients with your server. One such useful tool is a "slowcat", which behaves like the "cat"
command, but inserts a predetermined delay after every line that is printed (take a look at the
usleep() library function man page). This should help simulate user input, and keep the client
processes running long enough for them to interact with each other. To test your code more
thoroughly try using random delays instead of a fixed delay
One weakness of named pipes (FIFOs) is that multiple processes can write to the FIFO at the
same time. This means that if you have multiple client processes all trying to identify themselves
with the server, they all write to the FIFO and the server may end up getting bad messages, and
will not be able to connect to clients, etc. In other words, you need a sort of "mutex" for accessing
the server-fifo. One common way of achieving that is by creating a "lock" file (e.g. server-fifo.lck)
by using open() with the O_CREAT and O_EXCL flags to try to create the file exclusively. The
operation is "atomic" and will fail if the file already exists. Check out the man page for the open()
function. To "unlock", you may simply unlink() the .lck file.
You can verify some of the formatting of your output using the file "example_output.txt".
11
Download