[英]Why can't I connect to http server on localhost through a browser?
[英]Browser can't connect to localhost
我正在尝试使用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();
}
}
}
在while(true)
内部移动这两行:
client = server.accept();
System.out.println("Got connection.");
也在写入输出流后client.getOutputStream().write(httpResponse.getBytes());
关闭流:
client.getOutputStream().close();
您的浏览器挂起的原因是因为它不知道它将接收多少字节。
应用程序应使用[
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
因为它更清晰,而封闭的连接可能是由外部环境引起的。
您缺少必需的标头,并且没有刷新输出。
由于您似乎想使连接保持活动以处理多个请求,因此需要发送标头:
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 ...
客户端不确定服务器是否将发送更多数据。 您需要关闭服务器上的流,以使客户端知道响应已完成。
以下代码有效:不需要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();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.