Distributed Systems Lab/06 | |||||||
|
Lab 2 / Multi-Threaded Sockets File Transfer ServerIntroduction A threaded socket-based server is probably the easiest server type to understand. A server program almost always needs to handle more than one connection at a time. The reason is, since each connection gets its own thread, each thread can use simple blocking I/O on the socket. All other multi-connection server types use non-synchronous I/O of varying complexities in order to avoid thread overhead. A multi-threaded server isn't that different from the basic single-connection server. The architectures are fairly different, but some of the code is identical between the two server programs. Detailed Description In this assignment, you provide a server-side implementation of the DSGSFTP protocol that you used in Lab 1. Your objective is to develop a simple sockets-based, multi-threaded text file transfer server in Java (version 1.5). This server (that you actually used in Lab 1 ;-)) allows clients to connect to itself concurrently so that they can look for ASCII TEXT files and download them (i.e., you do not need to worry about transferring binary files such as images and programs). The functionality of your file transfer server should be coded into the class Server, which is stored in the file Server.java. The class should be a stand-alone program that will be directly invoked by java. Therefore, it must contain a static main() function. Your program is supposed to take exactly three command-line arguments. If more or less than three command-line arguments are passed to your program, or some error happens (e.g., cannot bind socket) you have to exit immediately with exit code 1 (i.e., System.exit(1)). In case of serious errors that prevent your server from running (e.g., cannot bind socket, etc.), catch the exception and terminate your program with exit code 1. In all other cases, (i.e., your server is shutdown gracefully) your program should exit with exit code 0. The synopsis of the program is as follows: java Server <server port> <shutdown port> <shutdown password> where
When your program is invoked with three arguments, it should bind to the server port (i.e., first argument) and listen for incoming connections from clients. At the same time, it should also bind to the UDP shutdown port (i.e., second argument) and listen for a valid shutdown UDP packet. A valid shutdown UDP packet is a packet that contains the shutdown password (i.e., third argument). If such a packet is received, the server should gracefully shut itself down after the last connected client quits (i.e., disconnects). Note that your server should use the UNIX file separator "/" in file and directory names (e.g., "/funny-stuff"). Your file transfer server uses a simple protocol to communicate with its clients. Here is the protocol description (to give you some "hands-on" experience reading protocol descriptions, we made it look like a typical protocol specification). If you have solved Lab 1, you will already be familiar with this protocol (so it does pay off to write code after all ;-)). Here is an Tests ZIP file you can use for testing. Unzip it and you will get the following file structure (Note that these files were created on Linux, you might have problems under Windows so copy them to the lab environment and test them there):
nc localhost 10900 < input.txt > out.txt Now compare the out.txt file with the output.txt file we provide (e.g., using diff)!If your server tries to bind to a TCP port that is already listening for a connection, an exception will be thrown by your server. Because many people will be testing their servers in the lab environment, such binding errors are probable. In order to prevent this from happening, we suggest that you use your dslabXXX number when choosing a port. For example, if your dslab number is dslab900, you should use 10000+900 = 10900 as the server port, and 10000+901=10901 as the listening UDP port. For example, user dslab900 would test his/her program using the following command (supposing that he/she is using the password dslab06): java Server 10900 10901 dslab06 We will ignore any debugging messages you may print to standard output or standard error (i.e., System.out, System.err in Java) so feel free to print anything you want (as long as you are not obscene and you don't insult our grading robot or us *grin*). When your server receives GET or LS requests from clients, it should read a local directory called pub and deliver its contents to clients. All files that clients should be able to see and download can be placed in this local directory. Suppose your pub directory is located at /home/uebungen/dslab/dslab900/pub. When a client issues a LS\n/\n request (i.e., list all the files in the root directory /), this request would be equivalent to getting a list of all files and directories in /home/uebungen/dslab/dslab900/pub/
Of course, it should not be possible for a client to see
directories or files outside of the pub directory. The
simplest trick somebody could use to by-pass your server could be a
so-called "directory traversal attack". That is, the client could
issue a request such as LS\n../\n and get a file listing of
Remarks Note that, in real life, passing a password as a command line argument is actually a very bad (and dumb) thing to do. A local attacker could issue a shell command such as ps auxww | grep Server to simply retrieve your password (!). However, we are doing this in DSLab just for the sake of simplicity. If you are interested in security issues and secure programming, then we suggest you take our introductory security course. Hints for Solving the Lab
Deliverables To submit your solution to us, you need to follow these steps:
Deadline You need to submit your solution until November the 16th, 17:59. Closing words Server is our success ;-) Last Modified: Fre Nov 10 15:32:01 CET 2006 |
Distributed Systems Group, Technical University of Vienna, Argentinierstrasse 8 / 184-1, 1040 Vienna, Austria, www.infosys.tuwien.ac.at |