我正在尝试使用Java设置简单的Web服务器,并且可以读取Web浏览器对我的机器的请求,但是Web浏览器似乎无法读取我的回复。您可以通过运行以下代码并尝试连接到http://localhost:8080来复制我的问题。
浏览器不确认任何响应,只是一直等待。有谁知道是什么原因造成的?我怀疑它与输出流有关,但我不知道出了什么问题。
我正在运行本教程中的代码的稍微修改的版本:https://javarevisited.blogspot.com/2015/06/how-to-create-http-server-in-java-serversocket-example.html
编辑:我刚刚用curl localhost:8080测试了连接,并且工作正常。不知道为什么网络浏览器有任何问题。欢迎您在自己的计算机上下载并测试此代码。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
public class SimpleHttpServer {
public static void main(String args[]) throws IOException {
Socket client = null;
try {
ServerSocket server = new ServerSocket(8080);
BufferedReader reader;
System.out.println("Listening for connection on port 8080 ....");
client = server.accept();
System.out.println("Got connection.");
while (true) {
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String temp = reader.readLine();
while ( temp != null && !temp.isEmpty() ) {
System.out.println("<"+temp+">");
temp = reader.readLine();
}
Date today = new Date();
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
client.getOutputStream().write(httpResponse.getBytes());
System.out.println("Sent: "+httpResponse);
Thread.sleep(1000);
}
} catch (Exception e) {
client.getOutputStream().close();
client.getInputStream().close();
client.close();
}
}
}
答案 0 :(得分:0)
将这两行移动到while(true)
内:
client = server.accept();
System.out.println("Got connection.");
还在写入输出流client.getOutputStream().write(httpResponse.getBytes());
之后,关闭该流:
client.getOutputStream().close();
答案 1 :(得分:0)
您的浏览器挂起的原因是因为它不知道它将接收多少字节。
除非[发送的消息类型]禁止,否则应用程序应使用[
Content-Length
]指示消息正文的传输长度。
在您的HTTP响应中包含Content-Length
,它应该可以工作:
Date today = new Date();
String body = today.toString();
String httpResponse = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: " + body.getBytes().length
+ "\r\n\r\n"
+ body;
这对于了解是否要保持连接打开以进行进一步的通信很有用,而不是关闭该连接以指示消息的结束并必须重新连接以进行进一步的通信。我也更喜欢Content-Length
,因为它更清晰,而封闭的连接可能是由外部环境引起的。
答案 2 :(得分:0)
您缺少必需的标题,并且没有刷新输出。
由于您似乎想保持多个请求的活动连接,因此需要发送标头:
Connection: keep-alive
您还需要告诉浏览器您要发送的内容以及发送的数量,以便知道响应何时完成:
Content-Type: text/plain
Content-Length: 999
工作代码:
// ... existing code ...
Date today = new Date();
String content = today.toString();
String httpResponse = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: " + content.length() + "\r\n" +
"Connection: keep-alive\r\n" +
"\r\n" +
content;
client.getOutputStream().write(httpResponse.getBytes());
client.getOutputStream().flush();
System.out.println("Sent: "+httpResponse);
// ... existing code ...
答案 3 :(得分:-1)
客户端不确定服务器是否将发送更多数据。您需要关闭服务器上的流,以使客户端知道响应已完成。
以下代码有效:不需要while
循环,只要结束输出流到客户端的结束,就可以发送响应。
编辑:其他人指出,您当然可以指定Content-Length
标头,依此类推。您还可以接受多个连接,依此类推。但是我认为您的示例很明显是一个玩具示例,因此这是最好的玩具答案-最简单的方法来使类似Hello,World的示例在没有其他背景信息的情况下工作。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
public class SimpleHttpServer {
public static void main(String args[]) throws IOException {
Socket client = null;
try {
ServerSocket server = new ServerSocket(8080);
BufferedReader reader;
System.out.println("Listening for connection on port 8080 ....");
client = server.accept();
System.out.println("Got connection.");
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String temp = reader.readLine();
while ( temp != null && !temp.isEmpty() ) {
System.out.println("<"+temp+">");
temp = reader.readLine();
}
Date today = new Date();
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
client.getOutputStream().write(httpResponse.getBytes());
System.out.println("Sent: "+httpResponse);
client.getOutputStream().close();
} catch (Exception e) {
client.getOutputStream().close();
client.getInputStream().close();
client.close();
}
}
}