Pool Thread Web Server - Need Help Implementing HTTP 1.1 keep alive
Hi guys, I have a pretty simple webserver, just 3 classes, very simple, but now I need to add HTTP 1.1 keep alive feature. I have two problems, 1) I'm not completely sure I understand the keep alive feature 2) I have no idea how to impliment it with my current code.
From my understanding HTTP 1.1 keep alive is used in order to reuse the socket so that you dont need to reopen it everytime. However, when you are listening to the serversocket and accepting new clients all the time, how can u figure out if you've already accepted the client before and already have a socket open? Okay sorry, I know I'm talking to much, i'll show my code, hopefully someone knows a simple way to impliment it.
Sincerely,
Hakim
package web;
import java.net.*;
publicfinalclass web{
publicstaticvoid main(String args[])throws Exception{
//The port of the webserver
int PORT = 5306;
ServerSocket listenSocket =new ServerSocket(PORT);
//The Queue that implements the ThreadPool
WorkQueue myserver =new WorkQueue(5);
//Run an infinite loop listening to the sockets and accepting more connections. It creates a new HTTPrequest to deal with the request and adds it to the queue to wait for execution
while(true){
HttpRequest request =new HttpRequest(listenSocket.accept());
myserver.execute(request);
}
}
}
package web;
import java.util.*;
publicclass WorkQueue
{
privatefinalint nThreads;
privatefinal Worker[] threads;
privatefinal LinkedList queue;
public WorkQueue(int nThreads)
{
this.nThreads = nThreads;
queue =new LinkedList();
threads =new Worker[nThreads];
for (int i=0; i<nThreads; i++){
threads[i] =new Worker();
threads[i].start();
}
}
publicvoid execute(Runnable r){
synchronized(queue){
queue.addLast(r);
queue.notify();
}
}
privateclass Workerextends Thread{
publicvoid run(){
Runnable r;
while (true){
synchronized(queue){
while (queue.isEmpty()){
try
{
queue.wait();
}
catch (InterruptedException ignored)
{
}
}
r = (Runnable) queue.removeFirst();
}
try{
r.run();
}
catch (RuntimeException e){
}
}
}
}
}
package web;
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.*;
import java.text.*;
finalclass HttpRequestimplements Runnable{
Socket socket;
staticfinal SimpleDateFormat webtime =new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z");
public HttpRequest(Socket socket){
this.socket = socket;
}
publicvoid run(){
try{
processRequest();
}catch (Exception e){
System.out.println(e);
}
}
privatevoid processRequest()throws Exception{
//Get references to sockets input and output streams
InputStream is = this.socket.getInputStream();
DataOutputStream os =new DataOutputStream(this.socket.getOutputStream());
//Set up input stream filter
BufferedReader br =new BufferedReader(new InputStreamReader(is));
//Get the request line of HTTP message
String requestLine = br.readLine();
//Extract the filename (ie take the second token
//Sample HTTP 1.0 First Line HEADER
// GET /path/file.html HTTP/1.0
// First token = Type of command (Get or Post)
// Second token = Filename
// Third token = HTTP Protocal (1.0 or 1.1)
StringTokenizer tokens =new StringTokenizer(requestLine);
tokens.nextToken();
String fileName = tokens.nextToken();
// Drop the slash at the begginning if there is a slash.
if(fileName.charAt(0) =='/')
fileName = fileName.substring(1,fileName.length());
// Open the requested file.
FileInputStream fis =null;
boolean fileExists =true;
try{
fis =new FileInputStream(fileName);
}catch (FileNotFoundException e){
fileExists =false;
}
// Construct the response message.
String statusLine =null;
String header =null;
String entityBody =null;
if (fileExists){
statusLine ="HTTP/1.1 200 OK \r\n";
if(fileName.endsWith(".htm") || fileName.endsWith(".html"))
header ="Content-type: text/html \r\n";
elseif(fileName.endsWith(".jpg") || fileName.endsWith(".jpeg"))
header ="Content-type: image/jpeg \r\n";
elseif(fileName.endsWith(".gif"))
header ="Content-type: image/gif \r\n";
elseif(fileName.endsWith(".txt"))
header ="Content-type: text/plain \r\n";
else
header ="Content-type: application/octet-stream \r\n";
webtime.setTimeZone(TimeZone.getTimeZone("GMT"));
String lastModified = webtime.format(new Date());
header +="Last Modified: " + lastModified;
}else{
statusLine ="HTTP/1.1 404 Not Found \r\n";
header ="NONE";
entityBody ="\n\n Not Found";
}
// Send the status line.
os.writeBytes(statusLine);
// Send the content type line.
os.writeBytes(header);
System.out.println(header);
// Send a blank line to indicate the end of the header lines.
os.writeBytes("\r\n");
// Send the entity body.
if (fileExists){
byte[] buffer =newbyte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while((bytes = fis.read(buffer)) != -1 )
os.write(buffer, 0, bytes);
fis.close();
}else{
os.writeBytes(entityBody);
}
//Close the streams
os.close();
br.close();
socket.close();
}
}
>

