Skip to content

EX24 - Parallel sockets

In the code snippets code-snippets/271 we have a seen a solution in Java and Python for serving basic HTTP requests.

The shown HTTP servers can, unfortunately, only serve one client at time (one endless while-true loop doing one accept()).

Question 1 - Threaded HTTP server

Change the code in such a manner that the server accepts multiple clients at the same time, using Threads serving the different clients. You can work on the Java or the Python example code.

Solution

A possible solution could look like this:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


public class HTTPThreadedServer {

    public static void main(String[] args) throws Exception {
        // socket creation
        int PORT = 8080;
        ServerSocket serverSocket = new ServerSocket(PORT);
        System.err.println("Server launched, listening on port: " + PORT);
        System.err.println("Number of active threads: " + java.lang.Thread.activeCount());

        // repeatedly wait for connections, and process
        while (true) {
            // blocks until a client tries to connect
            Socket clientSocket = serverSocket.accept();
            System.err.println("New client connected");

            // use this created socket for serving it
            new HTTPWriter(clientSocket).start();
        }
    }
}


class HTTPWriter extends Thread {
    private Socket clientSocket;

    public HTTPWriter(Socket sock){
        this.clientSocket = sock;
    }

    @Override
    public void run() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");

        try {
            // open conversation flow
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

            // all data received from the network socket will be read and output on the console
            String s;
            while ((s = in.readLine()) != null) {
                //System.out.println(s);
                if (s.isEmpty())    // empty line delimits the end of the input stream
                    break;
            }
            String myHTML = "<TITLE>HTTP Server</TITLE>";
            myHTML += "<P>This is my super duper test server page</P>";
            myHTML += formatter.format(LocalDateTime.now());
            myHTML += "<br>";
            myHTML += "ThreadID: " + Thread.currentThread().getId();
            myHTML += "<br>Number of running threads: " + java.lang.Thread.activeCount();
            int myLength = myHTML.length();

            out.write("HTTP/1.1 200 OK\r\n");
            out.write("Date: Fri, 15 May 2020 03:59:59 GMT\r\n");
            out.write("Server: MyOwnServer/0.0.1\r\n");
            out.write("Content-Type: text/html\r\n");
            out.write("Content-Length: "+myLength+"\r\n");
            out.write("Expires: Sat, 31 Dec 2030 00:59:59 GMT\r\n");
            out.write("Last-modified: Fri, 15 Aug 1996 23:59:59 GMT\r\n");
            out.write("\r\n");

            out.write(myHTML);

            // closing of the sockets
            System.err.println("Connection finished, closing sockets");

            out.close();
            in.close();
            clientSocket.close();
            sleep(6000);

        }
        catch (IOException | InterruptedException e){
            e.printStackTrace(System.out);
        }
    }
}

Question 2 - Python HTTP server library

Have a look at the basic http.server (https://docs.python.org/3/library/http.server.html) that comes out of the box with Python. Modify your threaded/multiprocessed code with a solution that uses the http.server module.