我正在尝试创建一个简单的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规范。