Простой http сервер повисает на считывании из потока

Пытаюсь написать простой http server на Java. Через браузер подключается, и повисает на чтении строки из потока. Работает, только если Socet будет создаваться в цикле. И вот здесь я ни как не могу разобраться почему.

public class SimpleServer {

private static ServerSocket serverSocket;
private static Socket socket;
private static InputStream in;
private static OutputStream out;

public static void main(String[] args) {
    try {
        serverSocket = new ServerSocket(80, 1, InetAddress.getByName("127.0.0.1"));

        while (true) {
            System.out.println("Wait for TCP-connection...");
            socket = serverSocket.accept();
            System.out.println("Client accepted\n");

            in = socket.getInputStream();
            out = socket.getOutputStream();

            readInputHeaders(in);
            transferData(out);

            in.close();
            out.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private static void readInputHeaders(InputStream in) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(in));
    while (true) {
        String s = br.readLine();
        if (s == null || s.trim().length() == 0) {
            break;
        }
        System.out.println(s);
    }
    System.out.println();
}

private static void transferData(OutputStream out) throws IOException {
    FileInputStream fis = new FileInputStream("E:/SomeFolder/htmlPage.html");
    byte[] buff = new byte[4096];

    while (fis.available() > 0) {
        fis.read(buff);
        out.write(buff);
    }
    out.flush();
}

}


Ответы (1 шт):

Автор решения: Alexey R.

В общем дело в том, что Вы не отправляете ответ. Я запустил код и немного подебажил его. сделал GET localhost из браузера.

В моем случае, все заголовки отобразились в консоли. Но из-за этого цикла:

while (true) {
    in = socket.getInputStream();
    readInputHeaders(in);
}

сервер вернулся обратно, снова ожидая увидеть заголовки. В запросе больше ничего нет, поэтому в сокет больше ничего не пишется. В то же время, соединение не закрывается клиентом, потому что браузер ожидает увидеть HTTP-response.

Из-за того что, браузер не закрывает сокет и не пишет туда ничего readLine() и висит.

Поэтому, Вам следует добавить логики в свой код. Определить есть ли боди, и если есть, продолжить его читать. Когда все прочитано, нужно ответить браузеру в соотв-ие с протоколом HTTP. Тогда браузер закроет соединение, сокет разорвется.

→ Ссылка