2010-09-12 45 views
0

我正在编写一个网络编程类的第一个家庭作业项目,它是用Java编写一个简单的Web服务器。我处于传输数据的地步,对于未经训练的人来说,我的宝贝服务器似乎工作正常。但是,我无法找到发送适当响应的方法。 (换句话说,一个无效的页面请求会显示一个404-ish的HTML页面,但是当我查看响应头时,它仍然会返回200 OK状态)。如何仅使用标准网络库发送HTTP响应?

我仅限于能够使用标准网络库进行套接字管理和标准I/O库来读取和写入输入流中的字节和字符串。下面是一些相关的代码:

从我的主...

  ServerSocket servSocket = new ServerSocket(port, 10);   // Bind the socket to the port 
     System.out.println("Opened port " + port + " successfully!"); 

       while(true) { 
      //Accept the incoming socket, which means that the server process will 
      //wait until the client connects, then prepare to handle client commands 
      Socket newDataSocket = servSocket.accept(); 
      System.out.println("Client socket created and connected to server socket..."); 

      handleClient(newDataSocket);        //Call handleClient method 
     } 

从handleClient方法......(一个循环内部解析请求方法和路径)

    if(checkURL.compareTo("/status") == 0) { // Check to see if status page has been requested 
        System.out.println("STATUS PAGE");  // TEMPORARY. JUST TO MAKE SURE WE ARE PROPERLY ACCESSING STATUS PAGE 
        sendFile("/status.html", dataStream); 
       } 
       else { 
        sendFile(checkURL, dataStream);   // If not status, just try the input as a file name 
       } 

从SENDFILE方法...

 File f = new File(where);            // Create the file object 
    if(f.exists() == true) {              // Test if the file even exists so we can handle a 404 if not. 
     DataInputStream din; 
     try { 
      din = new DataInputStream(new FileInputStream(f)); 
      int len = (int) f.length();          // Gets length of file in bytes 
      byte[] buf = new byte[len]; 
      din.readFully(buf); 
      writer.write("HTTP/1.1 200 OK\r\n");       // Return status code for OK (200) 
      writer.write("Content-Length: " + len + "\r\n");    // WAS WRITING TO THE WRONG STREAM BEFORE! 
      writer.write("Content-Type: "+type+"\r\n\r\n\r\n");    // TODO VERIFY NEW CONTENT-TYPE CODE 
      out.write(buf);             // Writes the FILE contents to the client 
      out.flush(); 
      out.close(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace();           // Not really handled since that's not part of project spec, strictly for debug. 
     } 
    } 
    else { 
     writer.write("HTTP/1.1 404 Not Found\r\n");       // Attempting to handle 404 as simple as possible. 
     writer.write("Content-Type: text/html\r\n\r\n\r\n"); 
     sendFile("/404.html", sock); 
    } 

任何人都可以解释如何,在条件从sendFile,我可以改变404块中的响应(就像我之前说的,响应头仍然显示200 OK)?这是对我的废话,我只是想使用HTTPResponse类,但我不能。 (另外,如果f.exists == true,则不显示内容长度和类型。)

谢谢!

+0

在我们没有看到的代码中,是否曾经将writer变量添加到输出流中?另外什么数据类型是作家和出? (我不想假设) – Sean 2010-09-12 23:22:51

+0

@gameaddict:我有PrintWriter作家=新的PrintWriter(sock.getOutputStream());在方法的最开始。对不起,不要试图保持简洁!另外,作家是PrintWriter,出来的是DataOutputStream。 – rownage 2010-09-12 23:32:37

+0

尝试从作者更改标题,并将其放入字符串中。然后将其添加到字符串格式的outputStream中。看看是否有帮助。你也可能想看看不要从你的其他地方调用sendFile()。如果没有找到404.html,你可能会以无限循环结束。你可以在...中做到这一点...如果(文件存在)文件是你传入的文件,否则文件是404文件.....然后做你的尝试。 – Sean 2010-09-13 00:30:51

回答

2

您看到的问题很可能与您的writer上缺少flush()有关。根据您使用的类型Writer,字节首先被写入需要刷新到流中的缓冲区。这可以解释为什么输出中缺少Content-LengthContent-Type。在将其他数据写入流之前只需刷新它。

此外,您致电sendFile("/404.html", sock);。您没有在这里发布完整的方法 - 但我想你在sendFile之内递归地调用它,因此发送状态为您的文件/404.html

+0

永远不会想到这一点。制作了一个不错的重要字符串,它拥有所有必要的东西,所以我可以只写一个write(),然后是一个flush,并且显示效果很好。谢谢! (此外,我递归调用sendfile,但冲洗问题解决了一切)。谢谢! – rownage 2010-09-13 00:29:29

3

编辑它看起来对我来说,在404的情况下,你要发送这样的事情:

HTTP/1.1 404 Not Found 
Content-Type: text/html 
HTTP/1.1 200 OK 
Content-Length: 1234 
Content-Type: text/html 

...其次是404页。请注意404之后的200行。这是因为您的404处理正在调用sendFile,它正在输出200响应状态码。这可能会让接收者感到困惑。

其错过了旧的答案:

的HTTP响应,并显示状态行开始,随后(任选地)由一系列报头的,然后(任选地)包括响应体。状态行和头都只是在一个定义的格式的线条,像(选择一个随机的例子):

HTTP/1.0 404 Not Found 

要实现你的小HTTP服务器,我建议有一个读通过the spec,看到什么反应应该看起来像。这有点概念上的飞跃,但它们确实只是根据商定的格式返回的文本行。 (嗯,这是我的一个理念的飞跃几年前,反正我是习惯了过分复杂的事情环境。)

它还可以帮助您最喜爱的命令行做这样的事情:

telnet www.google.com 80 
GET /thispagewontbefound 

...然后按Enter键。你会得到这样的东西:

HTTP/1.0 404 Not Found 
Content-Type: text/html; charset=UTF-8 
X-Content-Type-Options: nosniff 
Date: Sun, 12 Sep 2010 23:01:14 GMT 
Server: sffe 
Content-Length: 1361 
X-XSS-Protection: 1; mode=block 

...其次是一些HTML提供友好的404页面。上面的第一行是状态行,其余的是标题。状态行/标题和第一行内容(例如页面)之间有空行。

+0

对,我明白所有这些......但我认为这就是我在使用writer.write和out.write(buf)在sendFile方法中所做的事情?或者我在这里错过了更大的东西? – rownage 2010-09-12 23:06:15

+0

@rownage:呃,挺。对不起,'我应该去睡觉。更新后,我认为我看到了一个问题。无论是*问题是另一个问题,但肯定是*问题。 :-) – 2010-09-12 23:17:23

+0

当然是一个问题,是不是解决我的问题。感谢您的建议,但绝对有帮助! – rownage 2010-09-13 00:30:28

0

根据你所报告的症状,我认为真正的问题是你实际上没有和你的服务器通话!证据是:1)你无法获得404响应,2)200响应没有内容长度和类型。这些都不应该是可能的......如果你真的在谈论上面列出的代码。

可能:

  • 你谈话的较早版本的代码;即您的构建/部署周期中出现错误,您正在(错误地)尝试在Web容器(Jetty,Tomcat等)中部署/运行您的代码,或者您的客户端代码/浏览器实际上是您的代码/浏览器由于代理服务器,不正确的URL或其他类似信息而与其他服务器通信。

我建议您在代码的适当位置添加一些跟踪打印/日志记录以确认它实际上正在被调用。

相关问题