views:

89

answers:

3

I am writing a simple web server in java as an exercise. When I run the program it immediately starts into an infinite loop outputting "Error: null" into the console. I have a few try/catch statements that do

System.out.println("Error: " + e.getMessage());

I tried using the eclipse debugger to figure out where it starts, but when I run it in the debugger, it acts normally. Heres the two relevant clips of code:

public void run() {
        // Declare server socket
        ServerSocket serversocket = null;

        try {
            // Initialize serversocket on the port passed to
            // the constructor 
            serversocket = new ServerSocket(port);
            System.out.println("Server started on port " 
                    + Integer.toString(port));
        } catch (Exception e) {
            System.out.println("Fatal Error: " + e.getMessage());
        }

        while (true) {
            try {
                // Wait for connections
                Socket connectionsocket = serversocket.accept();
                // Get client IP
                InetAddress client = connectionsocket.getInetAddress();
                System.out.println(client.getHostName() + " connected.");

                // Read the request into a buffer
                BufferedReader input = new BufferedReader(
                    new InputStreamReader(connectionsocket.getInputStream()));

                // Prepare the output stream for sending headers
                // and requested file to the client
                DataOutputStream output = 
                    new DataOutputStream(connectionsocket.getOutputStream());

                http_handler(input, output);
            } catch (Exception e) {
                System.out.println("Error: " + e.getMessage());
            }
        }
    }

and

private void http_handler(BufferedReader input, DataOutputStream output) {
    int method = 0; // 1 get, 2 head, 0 not supported
    String http = new String();
    String path = new String();
    String file = new String();
    String user_agent = new String();
    try {
        // Two types of requests we can handle:
        // Get /index.html HTTP/1.0
        // HEAD /index.html HTTP/1.0
        String tmp = input.readLine(); // Read from the stream
        String tmp2 = new String(tmp);
        tmp.toUpperCase();
        if (tmp.startsWith("GET")) {
            method = 1;
        }
        if (tmp.startsWith("HEAD")) {
            method = 2;
        }

        if (method == 0) {
            try {
                // If the request is unsupported, send the error
                output.writeBytes(construct_http_header(501, 0));
                output.close();
                return;
            } catch (Exception e2) {
                System.out.println("Error: " + e2.getMessage());
            }
        }

        // Get whats between the spaces in the request
        // without the beginning slash
        int start = 0;
        int end = 0;

        for (int a = 0; a < tmp2.length(); a++) {
            if (tmp2.charAt(a) == ' ' && start != 0) {
                end = a;
                break;
            }
            if (tmp2.charAt(a) == ' ' && start == 0) {
                start = a;
            }
        }
        path = tmp2.substring(start + 2, end);

    } catch(Exception e) {
        System.out.println("Error: " + e.getMessage());
    }
    FileInputStream requestedfile = null;

    try {
        // Try to open the file
        requestedfile = new FileInputStream(path);
    } catch (Exception e) {
        try {
            output.writeBytes(construct_http_header(404, 0));
            output.close();
        } catch (Exception e2) {}
        ;
        System.out.println("Error: " + e.getMessage());
    }

    try {
        int type_is = 0;
        // Find out what the filename ends with so we can
        // put the right MIME type in the header

        if (path.endsWith(".zip") || path.endsWith(".exe")
                || path.endsWith(".tar")) {
            type_is = 3;
        } else if (path.endsWith(".jpg") || path.endsWith(".jpeg")) {
            type_is = 1;
        } else if (path.endsWith(".gif")) {
            type_is = 2;
        } else {
            type_is = 5;
        }
        // write out the header, 200 -> OK
        output.writeBytes(construct_http_header(200, type_is));

        // if the request was HEAD, we don't print the body
        if (method == 1) {
            while (true) {
                // read the file from the filestream and ouput through
                // the client outpustream
                int b = requestedfile.read();
                if (b == -1) {
                    break; // end of file
                }
                output.write(b);
            }
        }
        // Clean up
        output.close();
        requestedfile.close();
    } catch (Exception e) {}
}

** EDIT ** I printed the stack trace, and it is giving a NullPointerException on

Socket connectionsocket = serversocket.accept();

I thought this method was supposed to wait for connections. How do i keep it from doing what it's doing?

+1  A: 

my first guess would be the while (true) you have in the first chunk of code, but at a cursory read, I can't see anything that stands out. have you tried printing debug statements, rather than using the step-by-step debugger? I know what you mean about it working in debug mode, I've had that happen to myself before.

But a good few steps to take to track it down:

  1. Change every Error: statement to something like Error 1:, Error 2: and using the output of that to narrow down which chunk of code would be throwing the exception.
  2. Print the stack traces, which will narrow things down a LOT more than you could easily do otherwise
  3. Print out something for every line (or even every few lines, as needed) to visually walk through the code in the output window

This will let you narrow down the area that's giving you problems, and with a bit more fine-grained output statements, exactly which line and why.

Slokun
+1  A: 

Take this line:

System.out.println("Error: " + e.getMessage());

Change it to:

System.out.println("Error: " + e.getMessage());
e.printStackTrace();

This will help you track down the problem as it will show you the line numbers.

Dave Jarvis
A: 

If the ServerSocket initialization fails, you end up with an infinite null pointer exception because nothing exists to accept the connection on.

The.Anti.9
Now you should certainly leave a comment here and thank yourself ;)
Roman