Building a Multi-Threaded Web Server ✓ Solved

Building a Multi-Threaded Web Server

This project assignment involves developing a multi-threaded Web server in two stages. The final goal is to create a server capable of processing multiple simultaneous service requests in parallel, implementing Version 1.0 of HTTP as defined in RFC 1945. Initially, the server will display the contents of the HTTP request message it receives, followed by developing the ability to generate an appropriate response to these requests.

The implementation involves creating a main thread that listens for TCP connection requests on a fixed port and spawns a new thread for each request, allowing for concurrent processing.

In the first stage, you will write a server that only displays the requested HTTP message. After confirming that this functionality is working correctly, you’ll move on to develop the capability to respond appropriately to client requests. Testing can be done through a web browser, accessing your server using the specified port number in the URL.

For Part A, you will focus on the construction of the Web server code, beginning with the main class definition that listens for incoming connections and creates new threads to handle requests. For Part B, you will enhance the server by adding functionality to analyze client requests and send appropriate file responses, while also handling errors for non-existent files.

Paper For Above Instructions

The task of building a multi-threaded web server is an excellent way to gain a deeper understanding of server-client relationships, multi-threading, and HTTP protocols. This project will be broken down into two main parts as directed in the assignment instructions, enabling us to effectively manage complexity while developing our application.

Part A: Implementing a Multi-Threaded Web Server

To implement a multi-threaded web server, we need to create a main class that will handle incoming connections. This main class listens on a specific port and, upon receiving an HTTP request, it creates a new thread to handle the request. The following Java code presents a simplified version of our server implementation:

import java.io.*;

import java.net.*;

public final class WebServer {

public static void main(String argv[]) throws Exception {

int port = 6789;

ServerSocket serverSocket = new ServerSocket(port);

System.out.println("Server listening on port: " + port);

while (true) {

Socket clientSocket = serverSocket.accept();

HttpRequest request = new HttpRequest(clientSocket);

Thread thread = new Thread(request);

thread.start();

}

}

}

final class HttpRequest implements Runnable {

final static String CRLF = "\r\n";

Socket socket;

public HttpRequest(Socket socket) throws Exception {

this.socket = socket;

}

public void run() {

try {

processRequest();

} catch (Exception e) {

System.out.println(e);

}

}

private void processRequest() throws Exception {

InputStream is = socket.getInputStream();

DataOutputStream os = new DataOutputStream(socket.getOutputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(is));

String requestLine = br.readLine();

System.out.println();

System.out.println(requestLine);

// Process headers

String headerLine;

while ((headerLine = br.readLine()).length() != 0) {

System.out.println(headerLine);

}

os.close();

br.close();

socket.close();

}

}

Part B: Enhancing the Web Server to Respond to Requests

The next step involves extending the functionality of the server to handle HTTP requests properly. The server will analyze the request, extract the requested file name, and send back the content if it exists. The coding enhancements are as follows:

private void processRequest() throws Exception {

InputStream is = socket.getInputStream();

DataOutputStream os = new DataOutputStream(socket.getOutputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(is));

String requestLine = br.readLine();

System.out.println();

System.out.println(requestLine);

StringTokenizer tokens = new StringTokenizer(requestLine);

tokens.nextToken(); // Skip over the method should be "GET"

String fileName = "." + tokens.nextToken(); // Prepend a dot

FileInputStream fis = null;

boolean fileExists = true;

try {

fis = new FileInputStream(fileName);

} catch (FileNotFoundException e) {

fileExists = false;

}

// Prepare response

String statusLine;

String contentTypeLine;

String entityBody = null;

if (fileExists) {

statusLine = "HTTP/1.0 200 OK" + CRLF;

contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;

} else {

statusLine = "HTTP/1.0 404 Not Found" + CRLF;

contentTypeLine = "Content-type: text/html" + CRLF;

entityBody = "Building a Multi-Threaded Web ServerNot Found