简体   繁体   English

无法将流输出到浏览器

[英]Cannot output the stream to the browser

I just written a small program to test something, as below: 我刚刚编写了一个小程序来测试一些东西,如下所示:

public class Main {

    public static void main(String[] args){
        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        DataInputStream dataInputStream= null;

        BufferedWriter bufferedWriter = null;
        String line ;

        try {
            serverSocket = new ServerSocket(80);
            clientSocket = serverSocket.accept();

            dataInputStream = new DataInputStream(clientSocket.getInputStream());

            while((line = dataInputStream.readLine()) != null){
                System.out.println(line);
            }

            bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n Content-Length: 1354 \n <html>abcde<html/>");

            bufferedWriter.flush();

        } catch (IOException e) {
            System.out.println("socket port cannot be opened.");
            e.printStackTrace();
        } finally{
            try {
                serverSocket.close();
                bufferedWriter.close();
            } catch (IOException e) {
                System.out.println("socket port cannot be closed.");
                e.printStackTrace();
            }
        }


    }

}

I found the http response format from the internet, it should be correct. 我从互联网上找到了http响应格式,应该是正确的。 The problem is my browser keep on waiting for the response data (determine from the spinning logo), but the data is not returned successful. 问题是我的浏览器继续等待响应数据(从旋转徽标确定),但数据未成功返回。 What mistake I have made? 我犯了什么错误?

I connect to the Java program by typing "localhost" in the browser, I can print out the request string in Java program but only fail to send back the response. 我通过在浏览器中键入“localhost”连接到Java程序,我可以在Java程序中打印出请求字符串但只是无法发回响应。

Could it be the Content-Length header field? 它可能是Content-Length头字段吗? Try replacing the response with this: 尝试用以下方法替换响应:

bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n Content-Length: 18\n <html>abcde<html/>");

(Notice the Content-Length: 18 vs. the original Content-Length: 1354 ) (注意Content-Length: 18与原始Content-Length: 1354

I suspect the browser is waiting for your application to send more data. 我怀疑浏览器正在等待您的应用程序发送更多数据。

Edit: This works for me: 编辑:这对我有用:

import java.util.*;
import java.io.*;
import java.net.*;

public class Main {

    public static void main(String[] args) throws Exception{
        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        DataInputStream dataInputStream= null;

        BufferedWriter bufferedWriter = null;

        try {
            serverSocket = new ServerSocket(8080);
            clientSocket = serverSocket.accept();

            BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            while (clientSocket.getInputStream().available() > 0) {
                String line = reader.readLine();

                if (line == null) {
                    break;
                }

                System.out.println(line);
            }

            bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n\n <html>abcde<html/>");
            bufferedWriter.flush();
            clientSocket.close();
        } catch (IOException e) {
            System.out.println("socket port cannot be opened.");
            e.printStackTrace();
        } finally{
            try {
                serverSocket.close();
                bufferedWriter.close();
            } catch (IOException e) {
                System.out.println("socket port cannot be closed.");
                e.printStackTrace();
            }
        }


    }

}

The culprit was the while loop. 罪魁祸首是while循环。 The method you were calling to fetch more data was blocking until that data was available (which would never happen). 您调用以获取更多数据的方法是阻塞,直到该数据可用(这将永远不会发生)。 I'm not sure whether or not what I did was completely necessary, but it works. 我不确定我所做的是否完全必要,但它确实有效。

First things first, there are a few issues with the HTTP message being sent: Each line of an HTTP message is separated/ended by CR LF, rather than just a line feed (although I doubt this could be the problem, you should replace "\\n" with "\\r\\n"). 首先,发送HTTP消息存在一些问题:HTTP消息的每一行都由CR LF分隔/结束,而不仅仅是换行(尽管我怀疑这可能是问题,你应该替换“ \\ n“with”\\ r \\ n“)。 In addition, the Content-Length isn't equal to the real size of the message's body, which should be replaced. 此外,Content-Length不等于消息正文的实际大小,应该替换。 Before the actual body, all HTTP messages should have an empty line, which you have not. 在实际正文之前,所有HTTP消息都应该有一个空行,而您没有。 Finally, the forward slash at <html/> should also come before html , like this: </html> 最后, <html/>的正斜杠也应该出现在html之前,如下所示: </html>

To sum up: 总结一下:

bufferedWriter.write("HTTP/1.0 200 OK\r\nDate: Fri, 31 Dec 1999 23:59:59 GMT\r\nContent-Type: text/html\r\nContent-Length:18\r\n\r\n<html>abcde</html>");

Now for the real issue: the reading loop was constantly waiting for more data. 现在是真正的问题:阅读循环一直在等待更多的数据。 Comparing the result of readLine() to null actually doesn't do what you were looking for. 将readLine()的结果与null进行比较实际上并不能满足您的需求。 TCP connections make streams of data, and you never know if the client just stopped sending data in a particular moment. TCP连接产生数据流,您永远不知道客户端是否在特定时刻停止发送数据。 Instead, you can read until you find an empty line, which marks the end of the HTTP message's head. 相反,您可以阅读,直到找到一个空行,这标志着HTTP消息的结束。 Web browsers usually do not send additional content in GET messages, therefore you will not be missing any data. Web浏览器通常不会在GET消息中发送其他内容,因此您不会丢失任何数据。

    BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    while(!(line = reader.readLine()).isEmpty()){
        System.out.println(line);
    }

I see two problems: 我看到两个问题:

The content-length header says 1354 bytes will follow. 内容长度标题表示将跟随1354个字节。 You only are writing 20 or so. 你只写20左右。 Content-length is optional; 内容长度是可选的; don't include it if you're not using the correct value. 如果您没有使用正确的值,请不要包含它。

You need a blank line at the end of the headers and before the content: ".... Content-Length: xx\\n\\n<html>..." 在标题的末尾和内容之前需要一个空行: ".... Content-Length: xx\\n\\n<html>..."

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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