views:

106

answers:

4

hi,

im trying to write a simple web server in java.

right now ive only got a simple program but id like to extend it so that it can serve multiple browsers by establishing multiple tcp connections.

ive been reading about threading. my understanding is that you can make a new thread and that will continue as if its another program entirely. so with a new thread, it can be like there are 2 web servers which can serve 2 browsers, or x web servers which can serve x web browsers.

im a bit lost on how to create new threads in java though and to give each new thread a connection.

my thoughts are that i would have a loop like this which gets new connections and passes each new connection to a new thread

// make new ServerSocket
while (true) {
     Socket newConn = serverSocket.accept();
     // make new thread, and pass in newConn
}

can someone give me some guidance on how to move forward? (also if ive made an error somewhere, please do point it out. im new to threaded programming so its entirely possible ive not properly understood it)

rob

edit:

k thanks all.

i went and wrote something, that java tutorial helped a lot.

ive got a new issue now

i added a loop in my run() method in the new thread which contains a 10 second countdown (using Thread.sleep(1000)) whenever the server receives a request for an image, so i can see which threads are running when. (index.html has 4 images in it)

so i requested the index.html page and my server works fine. then i opened up about a dozen new tabs. my expectation was that the request for the index.html page would be instant but it would take 10 seconds for the images to be sent to the browser (because of that delay i put in there), at which point the server would receive the request for the next index.html page, and so on. overall, i thought that the dozen index.html pages would be served instantly while it would take 10 seconds for the 4 * 12 = 36 images to be served on all tabs.

what actually happened was it took 10 seconds to get the first 4 images, then 10 seconds for the next 4 images, etc. so rather than serving multiple web pages, my server just queues up requests and deals with one page at a time.

i think my program is at fault. but i feel like i might not properly understand how a browser interacts with a server. i thought the browser requests new objects as the html page is parsed. so my server should be receiving dozens of requests if i open a dozen pages. i tried opening up several tabs in FF and then several windows in FF but this did not help.

HOWEVER, when i opened up IE, FF and Chrome, and i asked for index.html at different times (about 2 seconds apart), it looked like each browser was receiving the page simultaneously, in other words, at one point, there were 12 different images being served, 4 to each browser

so i guess im looking for a bit of confirmation that this is the expected behavior? and if so, why is it that i could only see this behavior when i opened up 3 different browsers and not when i opened up multiple tabs?

(for those that asked, i plan ok taking a networks course next year, but im trying to do some of the basic stuff now. so half self learning, half h/w)

+1  A: 

You might also consider Netty and Java NIO. There's more than one way to do it.

duffymo
A: 

Sun's classic Java tutorial includes a section on programming with sockets that walks you through an example very similar to program you're trying to write.

Asaph
A: 

If you are looking for something robust look online for a working solution.
If it is for learning purposes, then create your own.
There are several ways to do this. The easiest is to do this As taken from the Java Tutorial :

import java.net.*;
import java.io.*;
public class MultiServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;

        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(-1);
        }

        while (listening)
        new MultiServerThread(serverSocket.accept()).start();

        serverSocket.close();
    }
}




import java.net.*;
import java.io.*;

public class MultiServerThread extends Thread {
    private Socket socket = null;
public MultiServerThread(Socket socket) {
super("MultiServerThread");
this.socket = socket;
}

public void run() {

try {
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
                new InputStreamReader(
                socket.getInputStream()));

    String inputLine, outputLine;
    KnockKnockProtocol kkp = new KnockKnockProtocol();
    outputLine = kkp.processInput(null);
    out.println(outputLine);

    while ((inputLine = in.readLine()) != null) {
    outputLine = kkp.processInput(inputLine);
    out.println(outputLine);
    if (outputLine.equals("Bye"))
        break;
    }
    out.close();
    in.close();
    socket.close();

} catch (IOException e) {
    e.printStackTrace();
}
}

}

You would implement your logic for processing your requests in:

KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);

You could optimize your code by putting your Threads in a Thread Pool so you did not need to create a new Thread each time.

The part below is subjective and depends on the types of requests and what you do with each one. If you have a lot of concurrent client requests then NIO is the way to go.
If your requests are short and you have over 10 concurrent ones create a pool.
If your requests are more than 100, then I would start looking at NIO.

Romain Hippeau
A: 

a web server is nothing but a glorified socket server with messaging. tech has been around since the very first network connection was made. i had a project about a year and a half ago that was similar to what your trying to do. Java NIO is the best bet to start with, has connection and thread pooling and all the advanced stuff that a web server needs, but its a bit complicated. if you want a VERY good baseline to start with, check out http://www.quickserver.org/ the system i wrote was based on this and it now handles about 45,000 devices on one server last i heard.

scphantm
Java NIO does *not* have 'connection and thread pooling', and the best place to start is java.net.
EJP