Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble sending HTTP response with Java Socket

Tags:

java

http

sockets

I've been trying to write the beginnings of a simple web server, but can't seem to get the response to get sent. I've tried every type of Output stream imaginable but nothing seems to work. I'm at a loss. Here are the two classes I'm using, sorry about some of the extraneous code:

package edu.xsi.webserver;

import java.io.IOException;
import java.net.ServerSocket;


public class WebServer {

int port;
ServerSocket server;

public WebServer(int port) throws IOException{

    this.port = port;
    this.server = new ServerSocket(port);
    Thread t = new Thread(new ServerExec());
    t.start();

}

public class ServerExec implements Runnable {

    public void run(){

        int i = 0;
        while (true) {

            try {
                new WebSession(server.accept(), i++);
                System.out.println("Should print before session");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }


}

public static void main(String[] args) {

    try {
        WebServer webServer = new WebServer(8888);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

This is the session class that handles the response.

package edu.xsi.webserver;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class WebSession implements Runnable {

Socket client;
int num;

public WebSession(Socket client, int num) {

    this.num = num;
    this.client = client;
    Thread t = new Thread(this);
    t.start();
}


public void run() {

    Scanner s = null;
    DataOutputStream out = null;

    try {

        s = new Scanner(client.getInputStream());
        out = new DataOutputStream(client.getOutputStream());

        //Get all input from header
        while (s.hasNextLine()) {
            System.out.println(s.nextLine());
        }
        out.writeBytes("HTTP/1.1 200 OK\r\n");
        out.writeBytes("Content-Type: text/html\r\n\r\n");
        out.writeBytes("<html><head></head><body><h1>Hello</h1></body></html>");

        s.close();
        out.flush();
        out.close();

    } catch(IOException ioe) {

        ioe.printStackTrace();
    }

}

}

like image 709
webhound Avatar asked Dec 03 '22 03:12

webhound


1 Answers

I've been struggling like crazy with a very similar issue.

After literally head-banding on the wall I found my issue was so trivial I kept on head-banging on the wall for a while.

Basically in my input while loop I was checking for a null line, but I forgot to check for an empty line (and subsequently break).

No guarantee it'll work the same for you but here's my one cent:

in = session.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = br.readLine()) != null) {
    System.out.println(line);
    // this seems to be the key for me! 
    // somehow I never get out of this loop if I don't 
    // check for an empty line...
    if (line.isEmpty()) {
        break;
    }
}
out = new BufferedWriter(
    new OutputStreamWriter(
        new BufferedOutputStream(session.getOutputStream()), "UTF-8")
);
out.write(OUTPUT_HEADERS + OUTPUT.length() + OUTPUT_END_OF_HEADERS + OUTPUT);
out.flush();
out.close();
session.close();

My constants are:

private static final String OUTPUT = "<html><head><title>Example</title></head><body><p>Worked!!!</p></body></html>";
private static final String OUTPUT_HEADERS = "HTTP/1.1 200 OK\r\n" +
    "Content-Type: text/html\r\n" + 
    "Content-Length: ";
private static final String OUTPUT_END_OF_HEADERS = "\r\n\r\n";

My "session" variable is a Socket object.

like image 187
Mena Avatar answered Dec 09 '22 14:12

Mena