CS276 Assignment 1
Due before class on January 28, 1999
In this assignment you will use UNIX sockets to
implement a simple WWW client and WWW server that communicate
using a restricted subset of http.
The main
objective of the assignment is to give you some hands-on experience
with sockets.
You should write two programs, a server program (process) and a
client program (process); the programs should be compiled separately, so that
they each have their own executable image.
The two processes will communicate with each other in a
connection-oriented manner using sockets.
The client process should first connect() to the server process
(after creating the socket, of course).
The client should then issue a simple GET http command. This is
done by writing the C-string:
"GET file-name HTTP/1.0\n"
into the client-to-server connection, where file-name is the name
of the .html file to be retrieved. This command is then
followed by a second string that
contains only the newline "\n" string.
For example, if the client sends the two strings:
"GET /index.html HTTP/1.0\n"
"\n"
to the http server, the http server will respond with the
file /index.html.
Your client process should write out all of the data returned by the
server (see below).
The server process should accept() an
incoming connection request. It should then look for the GET
request and pick out the file name. Note that a GET request
from a real WWW client may have several lines of optional
information following the GET. These optional lines, though, will
be terminated by a blank line (i.e., a line containing zero or more
spaces, terminated by a '\n' (newline) character.
Your server should first print out the
received GET command as well as any optional lines following the
GET (and preceeding the empty line).
The server should then respond with the line:
"HTTP/1.0 200 Document follows\n"
followed by a blank line (i.e., i.e, a string with only blanks,
terminated by a '\n').
The server should then send the contents of the requested document,
and then
close the socket created by the accept()
and wait to accept a new connection request.
If the document is not found, the server should respond with
"HTTP/1.0 404 Not Found"
as would a real http server (don't forget the \n).
Additional Notes:
- The RFC that defines the http protocol is avialable to you,
However,
you do not need to print it (or even read it) for this
assignment. Note that the RFC is 150 pages long!
- We would strongly suggest that everyone begin by writing a client,
and getting that client to work with server imj.ucsb.edu.
Then write a sequential server and test it with a WWW browser.
- In writing your code, make sure to check for an error return from
all system calls. (For this assignment, you do not need to check
return values for printf or exit however.)
If there is an error, the system declared global
variable, errno, will give you information about the
type of error that occurred, as shown in the example above.
- For the socket-related system calls(eg.fork() ), see man pages on the system, you may try xman command.
-
Note that read and write might return without having read
or written the full number of bytes requested. In such a case, these calls
will return a positive return value indicating the number of bytes actually
read or written. If the number does not correspond with the number
requested, be sure to loop back until all the data has been
transferred.
- Your processes should communicate using the reliable
stream protocol (SOCK_STREAM) and the Internet domain
protocols (AF_INET).
If you need to know your host's IP address, you can
telnet to your own machine and seeing the
dotted decimal address displayed by the telnet program.
You can also use the UNIX nslookup command
or you can take a look at the "hosts" file in the /etc directory.
- Most of you will be running both the client and server on the
same machine (e.g., by starting up the client and running it in the
background, and then starting the server [or vice versa).
Recall the use of the ampersand to start a process in the
background.
If you need to kill your server after you have started it, you
can use the UNIX kill command. Use the UNIX ps
command to find the process id of your server.
- Make sure you close every socket that you use in your program.
If you abort your program, the socket may still hang around and the
next time you try and bind a new socket to the port ID you
previously used (but never closed), you may get an error. Also,
please be aware that port ID's, when bound to sockets, are system-wide
values and thus other students may be using the port number
you are trying to use.
If your server is designed only to terminate upon receipt of a control-C
from the keyboard or of a kill signal, then you will want to use the
signal system call to make sure all sockets are closed before
your server terminates. (A call to exit will insure that
these sockets are closed gracefully before the server terminates.)
note that the signal system can be used to call a function that you
designate to be executed as soon as a control-C or a kill
signal is received. In the code fragment below, the user-supplied
function cleanExit() will be called when a control-C or kill signal
are received. The two calls to signal in the main routine
let the OS know that cleanExit should be called on a control-C or
a kill signal:
#include <signal.h>
........
main() {
........
signal(SIGTERM,cleanExit);
signal(SIGINT,cleanExit);
.......
} /* end of main */
void cleanExit() /* called on control-C or kill */
{
/* exit below will close open sockets*/
exit(); /* all done, so die */
}
For more info on UNIX Signals, checkout the page:
UNIX singals .
Testing your client and server
You can test your client and server as follows
- Your client can connect to the http server on imj.ucsb.edu
(i.e., connect to port 80 on IP host 128.111.52.12).
Your client can then do a get on "index.html" and that
file will be returned to your client by the real http server
on imj.ucsb.edu. Note that the http server will return several
lines of optional information following the
"HTTP/1.0 200 Document follows\n" line.
- Your server can be tested by using a Netscape (or other) browser
to be the client for your server. If your server is on a machine
imj.ucsb.edu (for example), listening on port 6090 (for example),
and you want
to GET a file called junk.html from this server, you
would enter "http://imj.ucsb.edu:6090/junk.html" as the URL
to open in your Netscape browser. This would cause Netscape to
contact your server at port 6090 and do a GET on junk.html
Note: Below a certain socket number you need the root password, which
is why you'll need to run on a socket other than 80.
What to Turn in
When you turn in your assignment, you should include:
- a program listing containing in-line documentation.
- a separate document of a page or so describing the
overall program design, a verbal description of ``how it works'',
and design tradeoffs considered
and made. Also describe possible improvements and extensions
to your program (and sketch how they might be made).
- a separate description of the tests you ran on your program to
convince yourself that it is indeed correct. Also describe
any cases for which your program is known not to work correctly.
- The test cases you should hand in should minimally be: (i)
your client retrieving "/index.html" from
imj.ucsb.edu:80. Your client should
print out the contents of the reply from the imj.ucsb.edu http
server as well as the contents of the file; (ii) a
test case where your client interacts with your server.
Assignment Grading
Class CS276, Tuesday, January 12, 1999