8

我正在家里托管一个网页。我使用 Java 制作了自己的 HTTP 服务器。这是一个SSCCE:

if(command.startsWith("GET"))
{
            //client is a socket on which I reply.
            PrintWriter pw = new PrintWriter(client.getOutputStream(), true);
    String commule = command.split(" ");
    if(commule[0].equals("GET"))
    {
        if(commule[1].contains("."))
        {
            File file = new File(GEQO_SERVER_ROOT + commule[1].substring(1).replaceAll("%20", " "));
            if(file.exists())
            {
                OutputStream out = client.getOutputStream();
                InputStream stream = new FileInputStream(file);

                String response = new String();
                response += "HTTP/1.1 200 OK\r\n";
                response += "Date: Thu, 08 Aug 2013 08:49:37 GMT\r\n";
                response += "Content-Type: text/html\r\n";
                response += "Content-Length: " + file.length() + "\r\n";
                response += "Connection: keep-alive\r\n";
                response += "\r\n";
                pw.write(response); //Assume I already initialized pw as a PrintWriter
                                    pw.flush();
                copy(stream, out);
                stream.close();
                out.close();
            }
            else
            {
                pw.write("<html><h1>The request 404ed.</h1>");
                pw.write("<body>The requested URL <b>" + commule[1] + "</b> could not be found on this server.</body></html>");
                                    pw.flush();
            }
        }
        else
        {
            BufferedReader br = new BufferedReader(new FileReader(GEQO_SERVER_ROOT + commule[1].substring(1) + "main.html"));
            String sCurrentLine;
            while ((sCurrentLine = br.readLine()) != null) 
            {
                pw.print(sCurrentLine);
            }
            br.close();
        }
    }
    else
    {
        pw.println("Unrecognized HTTP command.");
    }
}

这是 main.html 源代码:

<html>
<title>Geqo Server</title>
<body>Geqo server online and functioning!</body>
</html>

问题是当我尝试使用 Chrome 访问此页面时,它显示正确(至少在使用 127.0.0.1 时)。但是当我尝试在 127.0.0.1 上的 Firefox 上访问它时,它可以工作,但只是给了我 html 源代码。IE 也只给了我来源。谁能告诉我为什么 Firefox 和 IE 只显示源,而不是解析它?

我认为这包含一些线索(Firebug 截图):

萤火虫截图

我的消息来源似乎带有<pre>标签。我不知道为什么,但不是那种问题吗?

我端口转发。这是页面家伙:(http://110.172.170.83:17416/对不起,Stackoverflow 不允许数字链接。)

编辑:我发现了问题。但在我解释之前,感谢Bart的 SSCCE,我曾经将其与我的代码进行比较。这就是问题所在:if第八行的语句if(commule[1].contains("."))导致代码跳过了这里的大部分代码。在相应的else块中,甚至没有发送标头的命令。感谢艺术布里斯托尔指出这一点。

提前致谢。

4

4 回答 4

5

您的 printwriter 没有刷新(正如 Ernest 指出的那样),因此没有发送 HTTP 标头。查看直接连接的结果 - 它只返回原始数据,没有标题。

nc 110.172.170.83 17416
GET /

<html><title>Geqo Server</title><body>Geqo server online and functioning!</body></html>

编写 HTTP 服务器是一项艰苦的工作。除非这是为了练习,否则您应该使用轻量级的现有服务器,例如 Jetty,或 JDK 中内置的 Sun HTTP 服务器。

编辑 - APrintWriter真的不适合做 HTTP。它旨在处理逐行数据,例如正在写入磁盘的文件。它还依赖于特定于平台的文本编码和行尾设置。查看HTTP 规范以获取有关正确的 HTTP 服务器应该如何工作的更多详细信息。

于 2013-08-08T14:04:03.027 回答
1

autoFlush您使用第二个参数 启用

new PrintWriter(client.getOutputStream(), true)

http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html

与 PrintStream 类不同,如果启用了自动刷新,它将仅在调用 println、printf 或格式方法之一时完成,而不是在碰巧输出换行符时完成。这些方法使用平台自己的行分隔符概念,而不是换行符。

所以基本上你pw.write()没有刷新到输出流。所以你需要做的就是更换

pw.write(response);

pw.println(response);
于 2013-08-08T15:50:09.773 回答
1

缓冲似乎存在一些潜在问题。您将一些输出PrintWriter写入. 我肯定会在通话后添加通话。outoutpw.flush()pw.write()

于 2013-08-08T13:35:37.900 回答
0

您不发送任何响应标头。

pw我在您的源代码中找不到 的定义?

于 2013-08-08T14:01:23.347 回答