我正在尝试在java中编写一个简单的http服务器。到目前为止,这是我的代码:
服务器:
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class Server
{
static final int PORT = 8080;
final String REQUEST_FORMAT = "^GET (.*?) HTTP/1.1$";
final Socket client;
public Server(Socket s)
{
client = s;
}
public void run()
{
try
(Scanner in = new Scanner(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(),true);)
{
String request = in.findInLine(Pattern.compile(REQUEST_FORMAT));
System.out.println(request);
out.write("HTTP/1.1 200 OK");
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String []args)
{
try
(
ServerSocket server = new ServerSocket(PORT);
Socket client = server.accept();
)
{
Server s = new Server(client);
s.run();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
客户端:
import java.net.*;
import java.io.*;
import java.util.*;
public class Client
{
final int PORT = 8080;
String data = "GET /home/index.html HTTP/1.1";
public Client()
{
try
(Socket socket = new Socket("127.0.0.1",PORT);
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
Scanner in = new Scanner(new InputStreamReader(socket.getInputStream()));)
{
out.print(data);
String header1 = in.next();
System.out.println("header="+header1);
int status = in.nextInt();
System.out.println("status="+status);
String message = in.next();
System.out.println("message="+message);
}
catch(Exception ex)
{
}
}
public static void main(String []args)
{
Client c = new Client();
}
}
目前,客户端只是将一个示例请求写入服务器,服务器会写一个示例响应头。但是,在没有继续发送响应的情况下,服务器似乎在读取请求后无限期地等待客户端输入。请帮助解决此问题。
答案 0 :(得分:2)
如果您正在实施HTTP服务器,则需要实施HTTP协议。你不是那样做的。您需要仔细研究RFC 2616,特别是关于内容长度标题,连接:关闭和分块传输编码的部分,这里有不同的方法来确定传输的长度。
你也不会随时写行。 HTTP中的行终止符为\r\n,
,并且它不会出现在代码中的任何位置。
还有其他问题。您的服务器只接受一个客户端然后停止。它需要一个围绕接受代码的循环,它需要启动一个新线程来处理每个连接。
答案 1 :(得分:0)
您的服务器阻止在
String request = in.findInLine(Pattern.compile(REQUEST_FORMAT));
原因是,找不到模式,流也没有完成。
解决方案A :关闭套接字以便在客户端
写入out.print(data);
socket.shutdownOutput();
仅当您不想在客户端进行进一步写入时才有效。
解决方案B :
客户端:在数据之后写入换行符。
out.print(data);
out.print("\r\n");
out.flush();
服务器:使用Scanner.nextLine()和Matcher而不是Scanner.findInLine()
String line = in.nextLine();
Matcher matcher = Pattern.compile(REQUEST_FORMAT).matcher(line);
String request = null;
if(matcher.find()) {
//request = line.substring(matcher.start(),matcher.end());
request = matcher.group();//is similar to the commented line above
}