For network communications to work correctly a common language
or protocol must be established. The web protocol is the HTTP (Hypertext
Transfer Protocol). A HTTP request for a web page from a server
would go as:
GET
/index.html HTTP/1.0 \r\n\r\n
where GET
is the request keyword, /index.html
is the file requested, and HTTP/1.0
is the protocol/version. The final \r\n\r\n
indicates the two carriage return/linefeed pairs that must terminate
the line.
The code snippet from run()
shown below obtains the request line sent from the client by invoking
the readLine()
method of BufferedReader.
Then the request text is broken into tokens with the split()
method in the String
class (see Chapter
10 :Java : String Tools).
The tokens are checked to determine if the client sent the "GET"
command and, if so, to obtain the name of the file that the client
is requesting.
...
In the run() method in Worker...
//
First read the message from the client
String client_str =
client_in.readLine ();
System.out.println ("Client
message: "+client_str);
// Split the message
into substrings.
String [] tokens = client_str.split("
");
// Check that the message
has a minimun number of words
// and that the first
word is the GET command.
if ((tokens.length >=
2) &&
tokens[0].equals ("GET")) {
String
file_name = tokens[1];
// Ignore
the leading "/" on the file name.
if (file_name.startsWith
("/"))
file_name
= file_name.substring (1);
// If no
file name is there, use index.html default.
if (file_name.endsWith
("/") || file_name.equals (""))
file_name = file_name + "index.html";
// Check
if the file is hypertext or plain text
String content_type;
if (file_name.endsWith
(".html") ||
file_name.endsWith
(".htm")) {
content_type = "text/html";
}
else {
content_type
= "text/plain";
}
...
|
If the request from the client is valid, we then
read from the local file that the client is requesting and return
it to the client. As shown in the following code, to read the
file we first obtain a FileInputStream
for the file. We send text messages back to the client using the
PrintWriter
methods.
We note that the PrintWriter
methods don't throw IOException
and instead the class offers the checkError()
method, which returns true if an IOException
occurred. For the sake of brevity, we did not check for errors after
every print invocation. (In the DataWorker
class in Chapter 15,
we place the print invocations in utility methods that check for
errors and throw exceptions when they occur.)
...
Continue in the run() method in Worker...
//
Now read the file from the disk and write it to the
// output
stream to the client.
try {
//
Open a stream to the file.
FileInputStream
file_in = new FileInputStream (file_name);
//
Send the header.
pw_client_out.print
("HTTP/1.0 200 OK\r\n");
File
file = new File (file_name);
Date
date = new Date (file.lastModified ());
pw_client_out.print
("Date: " + date + "\r\n");
pw_client_out.print
("Server: MicroServer 1.0\r\n");
pw_client_out.print
("Content-length: " + file_in.available ()
+
"\r\n");
pw_client_out.print
("Content-type: " + content_type
+ "\r\n\r\n");
//
Creat a byte array to hold the file.
byte
[] data = new byte [file_in.available ()];
file_in.read
(data); // Read file into the byte
array
client_out.write
(data); // Write it to client output stream
client_out.flush
(); // Remember to flush output
buffer
file_in.close
(); // Close
file input stream
} catch
(FileNotFoundException e) {
//
If no such file, then send the famous 404 message.
pw_client_out.println
("404 Object Not Found" );
}
} else{
pw_client_out.println
("400 Bad Request");
}
} catch (IOException e) {
System.out.println (
"I/O error " + e );
}
// Close client socket.
try {
fClient.close ();
} catch (IOException e){
System.out.println ("I/O
error " + e );
}
// On return from run () the thread
process will stop.
} // run
...
|
The line "HTTP/1.0
200 OK\r\n" gives the protocol and version number of the
return message followed by the 200 code number that indicates that
the file has been found successfully and will be sent. This is followed
by the file's modification date, an identification of the server,
the length of the file and the file type (e.g. "text/html").
Finally, the whole file is sent in one big byte array via the write()
method of OutputStream.
If the file is not available, the program sends the "404
Object Not Found" error message, which is a common one for
Web users. If the request line had problems, a "400
Bad Request" error message is sent.
This short program provides a basic Web server that returns Web
files to browsers and any other client program that connects to
the port and uses the proper HTTP protocol. The Socket
and ServerSocket
classes, along with the I/O stream classes, do most of the work.
References & Web
Resources
Latest update: Dec. 9, 2004
|