无法将流输出到浏览器

时间:2012-08-03 17:14:13

标签: java browser io stream

我刚刚写了一个小程序来测试一些东西,如下所示:

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


    }

}

我从互联网上找到了http响应格式,应该是正确的。问题是我的浏览器继续等待响应数据(从旋转徽标确定),但数据未成功返回。我犯了什么错误?

我通过在浏览器中输入“localhost”连接到Java程序,我可以在Java程序中打印出请求字符串,但只是无法发回响应。

3 个答案:

答案 0 :(得分:3)

可能是Content-Length标头字段吗?尝试用以下方法替换响应:

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/>");

(请注意Content-Length: 18与原始Content-Length: 1354

我怀疑浏览器正在等待您的应用程序发送更多数据。

编辑:这对我有用:

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


    }

}

罪魁祸首是while循环。您调用以获取更多数据的方法是阻塞,直到该数据可用(这将永远不会发生)。我不确定我所做的是否完全必要,但它确实有效。

答案 1 :(得分:3)

首先,发送HTTP消息存在一些问题:HTTP消息的每一行都由CR LF分隔/结束,而不仅仅是换行(尽管我怀疑这可能是问题所在,你应将“\ n”替换为“\ r \ n”)。此外,Content-Length不等于消息正文的实际大小,应该替换。在实际正文之前,所有HTTP消息都应该有一个空行,而您没有。最后,<html/>处的正斜杠也应该在html之前,如下所示:</html>

总结一下:

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>");

现在是真正的问题:阅读循环一直在等待更多数据。将readLine()的结果与null进行比较实际上并不能满足您的需求。 TCP连接产生数据流,您永远不知道客户端是否在特定时刻停止发送数据。相反,您可以阅读,直到找到一个空行,这标志着HTTP消息的结束。 Web浏览器通常不会在GET消息中发送其他内容,因此您不会丢失任何数据。

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

答案 2 :(得分:1)

我看到两个问题:

内容长度标题表示将跟随1354个字节。你只写20左右。内容长度是可选的;如果您没有使用正确的值,请不要包含它。

标题末尾和内容前需要一个空行:".... Content-Length: xx\n\n<html>..."