|
|
|
|
Project 4: Applications
Your assignment is to design and implement a network application. The
application, "Fishtank," consists of a chatroom server and client.
You also have the option of building a second application for bonus
marks. The second application, "Fishweb," consists of a web server
and client. Because these applications involve server components, we
define the following "well-known ports:" a Fishtank server listens on
port 88, and a Fishweb server listens on port 80. Clients of these
servers should pick an unused local port to listen on for replies from
the servers.
Because multiple services and applications must co-exist in your code,
pay particular attention to structuring your code to make it easy to
add additional services and clients in a modular fashion.
As a reminder, if you connect your code up to class trawlers, other
students (and quite likely your instructor and TAs) will be able to
interact with you. Please show respect and good judgement; we don't
want to see any incidents involving inappropriate language or
"malicious" code.
As a way of helping us all do this, for this project, if you connect
to the class trawler, your node's name must contain your group name.
For example, if you are in group cse461z, and you connect two nodes
to the trawler, name them "cse461z1" and "cse461z2".
Fishtank
Fishtank is a chatroom service. As part of this, you will need to
build two components:
- Fishtank server: Your server should listen for and
accept connections from clients on the well-known Fishtank port
88. Each arriving connection is associated with one fishtank
client. The fishtank server performs two jobs: first, it accepts
fishtank commands from clients arriving on inbound connections;
second, for each client, it opens up a connection to that client
so that it can relay all chatroom messages to it. Accordingly,
the fishtank server accepts the following commands. (Note that a
fishtank command is delivered from a fishtank client to a fishtank
server inside a transport connection. Thus, the "payload" of a
transport connection to a fishtank server is a stream of commands,
and the connection will remain open as long as the client remains
connected to the server.)
- hello <username> <clientport>\r\n
This is the first command that a client must send to the
fishtank server. The "<username>" component of
the command is a user name associated with the client. The
<clientport> is the client-side port to which the
fishtank server should open a connection to relay messages.
Note that the quotes are not part of the command. Finally,
the "\r" indicates a carriage return character (ASCII
character 0x0d) and the "\n" indicates a newline character
(ASCII character 0x0a). All commands in fishtank are separated
with this "\r\n" delimiter. So, for example, a client might
send the following command:
hello gribble 211\r\n
which tells the fishtank server that a user named "gribble"
is connecting to the chatroom, and that the server should
connect to gribble's fishtank client on port 211. Usernames
should consist only of ASCII text characters; no spaces,
punctuation, or digits should be used. A client should only
send this command to the server once, at the beginning of the
connection.
- message <messagetext>\r\n
Using this command, a client sends the message
<messagetext> to the chatroom. The fishtank server
should relay this message to each of the connected clients,
so those clients can display the message to the users. So,
for example, a client might send the following command:
message hi everybody!\r\n
in order to send the message "hi everybody!" to the
chatroom.
- listusers\r\n
Using this command, a client asks the fishtank server to
send it a list of users currently connected to the
chatroom.
The fishtank server needs to be able to send responses to each of
these commands to the connected client. For each of the above
commands, the following actions are taken and response messages
are sent to the client:
- hello: If the fishtank server receives a hello command
from a client, the server will parse the command, and attempt
to open a connection to the client on the supplied port. Note
that the server will need to discover the address of the
client; your transport layer should provide the server with
this address when notifying the server application of a newly
arrived connection. If the server fails to open a connection
to the client, it will terminate the incoming connection on
which the hello message arrived. If the server successfully
opens the connection to the client, it will send back the
following reply to the client on that newly opened connection:
hello <username>\r\n
For example, if a client connects to the server and sends the
server the following command:
hello gribble 211\r\n
then the server opens a connection to port 211 on the client,
and the first message the server sends on that connection is:
hello gribble\r\n
- message: If the fishtank server receives a
message command from a client, the server will parse the
command, and then sends the message to all connected clients,
including the client that send the message. The message
should be send to each client using the following format:
message user <messagetext>\r\n
So, for example, imagine a client connects to the fishtank
server, and sends a hello message indicating a username
gribble. Then, sometime later, the client sends the
following command to the server:
message hi everyone!\r\n
The server should then send the following message to every
connected client:
message gribble hi everyone!\r\n
- listusers: If the fishtank server receives
a listusers command from a client, the server parses the
command, and then sends a reply message to that client
listing all of the connected user names. The format
of this reply message is:
listusers <username>,<username>, ... ,
<username>\r\n
So, imagine that 3 clients are connected, with user names
gribble, lillie, and safeer. Then, a client issues the
command listusers. The server will send the following
reply to that client:
listusers gribble,lillie,safeer\r\n
If only one user is connected, the reply will look like:
listusers gribble\r\n
At steady state, there will be two connections open per attached
client: one from the client to the server over which commands
flow, and one from the server to the client over which replies
flow. If either of these connections is shut down by either
endpoint, that client should be fully disconnected from the
server, and the other connection should be closed.
- Fishtank client: Your fishtank client should connect
to a specified fishtank server. The client should perform the
hello handshake upon connection. As well, it should accept
message and listuser commands (from the user or as part of a
script), and it should print out replies arriving from the server.
Fishweb (extra credit)
For extra credit, you can implement Fishweb, a simple Web server and
client. You will need to build the following two components:
- Simple Web server: Your server should accept connections
on the Transport port reserved for Fishweb, port 80. For each
arriving connection, it decodes the request using HTTP (see Peterson,
Chapter 9.2.2).
- Note that standard HTTP is implemented on TCP, which uses
bidirectional connections, while our Fishnet transport
protocol provides only unidirectional connections. To account
for this, we will add a new request header of the form
"Response-Port: 7". The client uses this header to indicate
the port it will use to listen for responses (e.g., port
7). Similarly, HTTP responses should echo the name of the
requested file in a header such as "Location: index".
- You should only support the very simplest form of "GET"
requests, as in "GET index http/1.0\r\nResponse-Port:
7\r\n". The server then establishes another connection in the
opposite direction, and if the file exists in the node's "www"
directory, sends the file to the other side, again using
HTTP. Use only the simplest reply format, e.g., "HTTP/1.0 202
Accepted\r\nLocation: index\r\nLength 20\r\n<file
contents>", or "HTTP/1.0 404 Not Found\r\nLocation:
index\r\n" if the file doesn't exist. The Length field gives
the length of the file contents in bytes.
- Web client: On the client side, the application
should be able to connect to a remote web server running on a node
at port 80. Your client should simply print the contents of the
downloaded file on the terminal. By default, your web server
should at least host the file "index". Note that we are using
HTTP/1.0, so that connections are terminated as soon as the file
has been downloaded; another connection must be established to
download additional files.
Requirements
As usual, you should strive to come up with a design and
implementation that will interoperate with other students' nodes.
So, you should obey the protocol specification precisely, but you
must try to be forgiving about implementation errors in other
students' code, where possible.
Discussion Questions
- The Fishtank application as described above uses a single
transport connection in each direction per client. A different
design would use a transport connection per command and reply.
Describe the pros and cons of these two designs.
- Describe which features of your transport protocol are a good
fit to the Fishtank application, and which are not. Are the
features that are not a good fit simply unnecessary, or are they
problematic, and why? If problematic, how can we best deal
with them?
- Even if you did not implement the extra credit Fishweb
application, read through its protocol specification above.
Describe which features of your transport protocol are a good fit
to this application, and which are not. Are the features that are
not a good fit simply unnecessary, or are they problematic, and
why? If problematic, how can we best deal with them?
- Describe one way in which you would like to improve your design.
Turn In
Turn in electronic and paper material as follows.
- Electronically turn in all of the source code for your node.
- In class on the due date, turn in your design document, a
printout of your code, and answers to the discussion questions.
As well, provide a "man page" for your node that tells us how
to use it to connect to a Fishtank server of our choosing, and
how to set up a Fishtank server using your node.
- Use Fishtank to connect to as many other groups' Fishtank
servers as you can. Record which node (node's name) you were able
to connect to, and the list of users currently connected to that
node. Use the script command to capture a session in which you
interact with your own server, and a second session in which you
interact with another group's server.
Grading guidelines
Each part of the project is graded on a 5 point (0-4) scale, multiplied by the
weight of the part. The weighted grades from all parts of the project are added
together to produce the final grade. There is an extra credit component to this
project.
The five point scale is based on how well you show your understanding of the
problem, and in case of code how well your implementation works:
0 - nothing turned in
1 - show minimal understanding of the problem / most things don't work
2 - show some understanding of the problem / some things work
3 - show a pretty good understanding of the problem / most things work
4 - show excellent understanding of the problem / everything works
The weights for the parts of project 3 are:
Fishtank implementation: 1/2 of total grade
Write-up of your design decisions: 1/4 of total grade
Answers to discussion questions: 1/8 of total grade
Print-out of captured output: 1/8 of total grade
Fishweb (extra credit)
|