File Server/Client Assignment
- Due Date:
- November 28, 1995
- Deliverables:
-
When the project is complete, send me an email telling the path to
the project directory, which is to be empty except for the RCS subdirectory.
You may use SCCS instead of RCS, but RCS is preferred. Typing make
in the project directory is to cause two programs, a client and a server,
to be built. Then, typing make install is to cause the executable
files to be moved to ~/bin and the man pages for the two programs to be
moved to ~/man/man1. After make install the project directory
must be empty again. The make commands must require no interactions
with the user, even if repeated again.
If you want to leave a message
for me that doesn't belong in the man pages or your code documentation,
you may leave a text file in the project directory named README, but a
README file is neither required nor expected for this assignment.
- Requirements:
-
In addition to the information given here, be sure to consult the
Grading Form for this assignment,
which includes additional information about the requirements for this
project.
Project Description
One program you are to write is an Internet server daemon
which is to process file transfer requests from remote clients. The
server daemon is patterned after the Unix ftpd(8) daemon, which
implements the protocol defined by the Internet standard, RFC-959.
Your server, however will implement a simpler protocol than the one used
by ftpd. The other program is an ftp client that interacts
with your server to allow users to transfer files between the server's and
client's host machines. Do not name your programs ftpd and ftp
because those names should only be used by programs that implement the
protocol specified in RFC-959.
Note: Feel free to get a copy of RFC-959
to look at, but please do not print it out in the lab. It is very long,
you do not need it to do this project. Save a tree and save our
printer!
The Protocol
The protocol your client and server are to follow consists of an
exchange of requests from the client to the server and
replies from the server to the client.
Each request consists of
a text line that begins with a keyword, any parameters needed by that
keyword, and ends with the ASCII sequence
<cr><lf>
. No request will be more than 128
characters long, including the termination characters, but one type of
request (STOR
, see below) is followed by a stream of bytes
(the contents of a file) that the server reads without interpreting
(it writes them to a file in its current working directory).
Each reply
consists of a three-digit string of decimal characters followed by an
explanatory phrase of text terminated by <cr><lf>
.
The decimal string is designed to be
interpreted by your client, and the text phrase is designed to be read
by the user. No reply will be more than 128 characters long, but some
replies are followed by some number of bytes that the client reads and
then writes either to a file or to the user's screen depending on the type
of request that generated the reply.
The request keywords and their parameters are as
follows:
PWD
- The client requests the server to return a
string telling the current working directory on the server's host.
CWD <pathname>
- The client requests the server to
change its current working directory to the
<pathname>
specified in the command, which is given relative to the server's
current working directory.
DIR
- The client requests the server to send a
reply containing a listing of the file
names and sizes of all files in its current working directory.
RETR <filename>
- The client requests the server
to send a reply specifying the number of bytes in the named file,
followed immediately by the contents of the file. The client writes
the file into its own current working directory.
STOR <filename> <size>
- The client requests the
sever to store the named file, of the specified size, in the
server's current working directory. This message is always exactly
56 bytes long, which allows for up to 32 bytes for the name of the file
and up to 16 bytes for the size. Immediately after this message, the
client writes the contents of the file to the server, which writes the
file into its own current working directory.
The server uses the following reply codes to send messages to its
clients:
200 OK
- This code is used to indicate successful
completion of a request that needs no other information. It is used
following successful processing of CWD and STOR commands.
212 <size>
- This code is the reply to a DIR,
PWD, or RETR request, and specifies how many bytes the server is about
to transmit. It is always exactly 23 bytes long, which allows for a 16
digit <size> parameter. Immediately after the 23 byte message,
the server sends <size> bytes of information, which the client
processes in a manner that depends on what type of request it made.
500 Command Unrecognized
- A message from the client
did not begin with one of the keywords that the server recognizes.
501 Invalid Parameter
- A STOR, RETR, or CWD request
could not be processed because of the value of a parameter.
502 Command Not Implemented
- As you develop your
programs in a sequence of steps, your client might make a request that
you haven't implemented yet in your server, and this should be the
server's reply.
The User Interface
The client program accepts the following commands from the user:
pwd
- This command causes the client to send a PWD request to
the server and to display the server's current working directory.
ls
- This command causes the client to send a DIR request
to the server and to display the directory listing that the server returns.
cd <directory>
- This command causes the client to
send a CWD request to the server.
get <filename>
- This command causes the client
to send a RETR request to the server and to store the retrieved file in
the client's current working directory. The client displays the
number of bytes in the file, and some sort of progress
indicator as the file is received. A satisfactory progress indicator
would be to show the digits "9 8 7 ... " one at a time each time
10% of the file is received.
put <filename>
- This command causes the client to
send a STOR request to the server, followed by the contents of the named
file. This command also displays the number of bytes to be transferred
and a progress indicator during transfer.
exit
- This command causes the client to close its
connection with the server and to exit.
Development Steps
The project is to be done as a sequence of steps, each of which is to
correspond to an RCS major version number. All the files needed to
make version 1 of the program must have version numbers in the form
"1.x" (where x can be any number greater than zero); all the
files needed to make version 2 of the program must have version
numbers in the form "2.x" and so on.
- Version 1
-
Create client and server programs that connect with each other using the
default port number assigned to you, and program both to accept an
alternate port number from the command line. Your default port number
is the last four digits of your ID#. (If the last four digits of your
ID# are 0403 use 1413 instead.) Select alternate port numbers from
your assigned number plus a number between 1 and 10.
The server is to be a concurrent server which forks a process for
each client connection. The child processes are to execute a function
which must be defined in a separate source file from the server parent
process.
For this version, the client and server do not write or read anything
over their socket connection.
Make sure the client program terminates normally if the user enters
an exit command. Make sure you can connect to the server
repeatedly with your client. Make sure you can connect to the server
several times concurrently with your client. Make sure the server
leaves no zombie (defunct) processes.
- Version 2
-
For this version, implement the user commands pwd and cd.
The server can handle PWD and CWD requests using the getcwd(3) and
chdir(2) calls. The server should always be able to respond to
PWD successfully, but chdir(2) may fail for various reasons, and
the client and server must handle this situation properly.
- Version 3
-
Implement the ls command. You can use the system(3)
function to run ls(1) with output redirected to a file. The
trick is that the name of the file must be unique across all concurrent
clients. A process can use getpid(2) to generate unique file
names. The /tmp directory is available for temporary files, so a
temporary file might be in the form /tmp/<pid>, where <pid> is the
decimal character representation of the process id returned by
getpid(2). Use the fstat(2) call to determine the size
of the temporary file in order to construct the
212 <size>
reply message. The server deletes the listing file after it has sent
it to the client.
- Version 4
-
Implement the get and put commands. Once you have completed
Version 3, there should be no new programming techniques involved in
implementing these commands.
When you test Version 4, be sure you have the client and server
using different working directories during file transfers or you are
likely to get unpleasant results.
Christopher Vickery
Queens College of CUNY