我正在尝试创建一个简单的html服务器,它将从浏览器读取请求,从请求中解析请求的文件,然后将适当的html提供给浏览器。我需要能够处理多个请求,因此我当前有一个服务器类充当另一个可运行类requesthandler的父类。每次在服务器上建立连接时,都会运行可运行类requesthandler的新实例。

package server;

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

public class Server {

    public static void main(String[] args){
        try{
            ServerSocket serverSocket = new ServerSocket(8000);

            for(;;){
                Object block = new Object();
                RequestHandler handler = new RequestHandler(block, serverSocket);
                handler.start();

                try{
                    synchronized(block){
                        System.out.println("Server thread paused...");
                        block.wait();
                        System.out.println("Server thread creating new RequestHandler...");
                    }
                }catch(InterruptedException e){
                    System.out.println("Can't be interrupted!");
                    e.printStackTrace();
                }
            }

        }catch(IOException e){
            System.out.println("IOException!");
            e.printStackTrace();
        }
    }
}

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class RequestHandler extends Thread {

    Object block;
    ServerSocket serverSocket;
    BufferedReader socketReader;
    PrintWriter socketWriter;

    public RequestHandler(Object block, ServerSocket serverSocket){
        this.block = block;
        this.serverSocket = serverSocket;
    }

    @Override
    public void run() {
        try{
            System.out.println("Waiting for request...");
            Socket clientSocket = serverSocket.accept();
            System.out.println("Connection made.");

            synchronized(block){
                System.out.print("Notifying server thread...");
                block.notify();
                System.out.println("...done");
            }

            socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            socketWriter = new PrintWriter(clientSocket.getOutputStream(), true);

            String input;
            while((input = socketReader.readLine()) != null){
                System.out.println(input);
            }
        }catch(IOException e){
            System.out.println("IOException!");
            e.printStackTrace();
        }
    }

}

我遇到的问题是,我不确定如何组合请求的所有行,以便可以分析请求的文件。如果它只是不断地等待请求输入,我将永远无法解析整个请求。我怎样才能解决这个问题?

最佳答案

只有当客户端和服务器之间的连接关闭时,while循环才会断开。由于客户端在发送请求后正在等待同一连接的响应,因此连接将保持打开状态,因此readline()将阻塞。在while循环中,必须在每行之后检查是否已到达请求数据的末尾。对于get请求,您必须在http头后面查找一个空行。对于post请求,必须解析传入的头以查找。然后处理剩余的标题寻找空白行(就像在GET的情况下)。一旦找到空白,就必须读取字节。此时,您知道您已经完成了对请求数据的处理,应该脱离读取循环。
有关详细信息,请阅读http规范。

10-06 04:21
查看更多