简体   繁体   English

浏览器无法连接到本地主机

[英]Browser can't connect to localhost

I'm trying to setup a simple web server in java, and I can read the web browser's request to my machine, but the web browser can't seem to read my reply. 我正在尝试使用Java设置一个简单的Web服务器,并且可以将Web浏览器的请求读取到我的机器上,但是Web浏览器似乎无法读取我的回复。 You can duplicate my issue by running the code below and attempting to connect to http://localhost:8080 . 您可以通过运行以下代码并尝试连接到http:// localhost:8080来复制我的问题。

The browser doesn't acknowledge any response, and just keeps waiting forever. 浏览器不确认任何响应,只是一直等待。 Does anyone know what is causing this? 有谁知道是什么原因造成的? I suspect it's related to the output stream but I don't know what's wrong. 我怀疑它与输出流有关,但我不知道出了什么问题。

I'm running a slightly modified version of the code in this tutorial: https://javarevisited.blogspot.com/2015/06/how-to-create-http-server-in-java-serversocket-example.html 我正在本教程中运行代码的略微修改版本: https : //javarevisited.blogspot.com/2015/06/how-to-create-http-server-in-java-serversocket-example.html

EDIT: I just tested the connection with curl localhost:8080 and it worked fine. 编辑:我刚刚测试与curl localhost:8080的连接,并且工作正常。 No clue why the web browser has any issues. 不知道为什么网络浏览器有任何问题。 You're welcome to download and test this code on your own machine. 欢迎您在自己的计算机上下载并测试此代码。

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();
        }
    }
}

Move these two lines inside while(true) : while(true)内部移动这两行:

client = server.accept();
System.out.println("Got connection.");

also after writing to output stream client.getOutputStream().write(httpResponse.getBytes()); 也在写入输出流后client.getOutputStream().write(httpResponse.getBytes()); close the stream: 关闭流:

client.getOutputStream().close();

The reason your browser is hanging is because it doesn't know how many bytes it is going to receive. 您的浏览器挂起的原因是因为它不知道它将接收多少字节。

According to the HTTP/1.1 RFC 根据HTTP / 1.1 RFC

Applications SHOULD use [ Content-Length ] to indicate the transfer-length of the message-body, unless this is prohibited by [the type of message you are sending]. 应用程序应使用[ Content-Length ]指示消息正文的传输长度,除非[您正在发送的消息类型]禁止这样做。

Include Content-Length in your HTTP response and it should work: 在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;

This is useful to know if you want to keep the connection open for further communication, rather than closing it to indicate the end of a message and having to reconnect for further communication. 这对于了解是否要保持连接打开以进行进一步的通信很有用,而不是关闭该连接以指示消息已结束并且必须重新连接以进行进一步的通信。 I also prefer Content-Length because it is more clear, whereas a closed connection could've happened from external circumstances. 我也更喜欢Content-Length因为它更清晰,而封闭的连接可能是由外部环境引起的。

You are missing required headers and you're not flushing the output. 您缺少必需的标头,并且没有刷新输出。

Since you seem to want to keep the connection alive for multiple requests, you need to send header: 由于您似乎想使连接保持活动以处理多个请求,因此需要发送标头:

Connection: keep-alive

You also need to tell the browser what you're sending, and how much, so it knows when the response is complete: 您还需要告诉浏览器您要发送的内容以及发送的数量,以便知道响应何时完成:

Content-Type: text/plain
Content-Length: 999

Working code: 工作代码:

// ... 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 ...

The client isn't sure the server isn't going to send more data. 客户端不确定服务器是否将发送更多数据。 You need to close the stream on the server to let the client know the response is complete. 您需要关闭服务器上的流,以使客户端知道响应已完成。

The following code works: the while loop is not needed, and you can just send the response, as long as you end by closing the output stream to the client. 以下代码有效:不需要while循环,只要关闭输出流到客户端即可结束,就可以发送响应。

EDIT: Others have pointed out that you could, of course, specify a Content-Length header, and so forth. 编辑:其他人指出,您当然可以指定Content-Length标头,依此类推。 You could also accept multiple connections, and so forth. 您还可以接受多个连接,依此类推。 But I think it's clear that your example was a toy example, and so this is the best toy answer -- the simplest way to get something like your Hello, World example working without additional background information. 但是我认为您的示例很明显是一个玩具示例,因此这是最好的玩具答案-最简单的方法来使类似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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM