我正在尝试创建一个简单的HTML服务器,它将从我的浏览器中读取请求,从请求中解析所请求的文件,然后将适当的HTML提供回浏览器。我需要能够处理多个请求,所以我目前有一个Server类充当另一个可运行类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();
}
}
}
我遇到的问题是我不确定如何组合请求的所有行,以便我可以解析所请求的文件。如果它只是不断地等待请求输入,我将永远不会达到我可以解析整个请求的程度。我该如何解决这个问题?
答案 0 :(得分:3)
只有在客户端和服务器之间的连接关闭后,您的while循环才会中断。由于客户端在发送请求后正在等待相同的连接以获得响应,因此连接将保持打开状态,因此readline()将阻止。在while循环中,您必须在每一行之后检查您是否已到达请求数据的末尾。对于GET请求,您必须在HTTP标头后面查找空行。对于POST请求,您必须解析查找< Content-Length:N>的传入标头。然后处理剩余的标题寻找空白行(就像在GET情况下一样)。找到空白之后,你必须阅读< N>字节。此时,您知道已经完成了处理请求数据的处理,并且应该突破读取循环。
阅读HTTP规范以获取详细信息。
答案 1 :(得分:1)
第一行为您提供请求方法以及请求的路径,以下行是请求标题,标题块以空行结束。
那就是说,你正在重新发明轮子:你可以使用com.sun.net.httpserver.HttpServer