听取HTTP请求的正确方法是什么? [英] What is the proper way to listen to HTTP requests?

查看:147
本文介绍了听取HTTP请求的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个非常简单的,相当低级别的HTTP(好吧,HTTP的一部分)服务器作为练习,以便更加熟悉我一直在避免的整个网络事物。第一次尝试它的效果相当不错(并不是我建议任何人实际使用它,但是我会告诉它)。现在的问题是GET操作失败很多(刷新有帮助,但它不是很好 - 下面的详细信息),我认为这是因为我读取请求的方式(我相当确定我的路线有效):

I've written a very simple, rather low level HTTP (well, part of HTTP) server as an exercise to get more familiar with this whole web thing I've been avoiding all the time. It works reasonably well for a first attempt (not so much that I would recommend anyone to actually use it, but it does what I tell it to). Now the problem is that the GET operation fails a lot (refreshing helps, but it's not very nice - details below), I assume this is because of the way I read requests (I am fairly certain my routes work):

void start()
{
    //...
    try(ServerSocket webSock = new ServerSocket(47000) {
    //...
        while(running) {
           try {
               Socket sock = webSock.accept();
               //read/write from/to sock 
           }
           //...
           Thread.sleep(10);
        }
    } 
}

(完整代码: http: //pastebin.com/5B1ZuusH

我不确定 我做错了什么。

I am not sure exactly what I'm doing wrong though.

我收到错误:

This webpage is not available
The webpage at http://localhost:47000/ might be temporarily down or it may have moved permanently to a new web address.
Error 15 (net::ERR_SOCKET_NOT_CONNECTED): Unknown error.

相当多(整页不加载),有时脚本或图片也不加载。如果需要,我可以发布整个代码,但其余的主要是样板文件。

quite a bit (entire page doesn't load), sometimes scripts or images don't load either. If required, I could post the entire code, but the rest is mostly boilerplate.

推荐答案

[另一个更新]

确定澄清我的回答,这是一个简单的Web服务器,显示如何读取GET请求。请注意,它在同一连接中处理多个请求。如果连接关闭,程序将退出。通常,虽然我可以在连接关闭并退出程序之前从同一个Web浏览器发送一些请求。这意味着您不能使用end-of-stream作为消息结束的信号。

OK to clarify my response, here is a trivial web server that shows how to read GET requests. Note that it handles multiple requests in the same connection. If the connection closes, the program exits. Typically though I can send a number of request from the same web browser before the connection closes and the program exits. This means you cannot use end-of-stream as a signal the the message is over.

请注意,我从不使用手写的Web服务器来处理任何真实的事情。 。我最喜欢的是Tomcat,但其他框架也很好。

Please note that I never use a hand-written web-server for anything real. My favorite is Tomcat, but the other frameworks are fine too.

public class MyWebServer
{
   public static void main(String[] args) throws Exception
   {
      ServerSocket server = new ServerSocket(47000);
      Socket conn = server.accept();
      BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

      // don't use buffered writer because we need to write both "text" and "binary"
      OutputStream out = conn.getOutputStream();
      int count = 0;
      while (true)
      {
         count++;
         String line = reader.readLine();
         if (line == null)
         {
            System.out.println("Connection closed");
            break;
         }
         System.out.println("" + count + ": " + line);
         if (line.equals(""))
         {
            System.out.println("Writing response...");

            // need to construct response bytes first
            byte [] response = "<html><body>Hello World</body></html>".getBytes("ASCII");

            String statusLine = "HTTP/1.1 200 OK\r\n";
            out.write(statusLine.getBytes("ASCII"));

            String contentLength = "Content-Length: " + response.length + "\r\n";
            out.write(contentLength.getBytes("ASCII"));

            // signal end of headers
            out.write( "\r\n".getBytes("ASCII"));

            // write actual response and flush
            out.write(response);
            out.flush();
         }
      }
   }
}

[原始回复]


收听HTTP请求的正确方法是什么?

What is the proper way to listen to HTTP requests?

对于我们大多数人来说,正确的方法是使用设计良好的Web服务器框架,例如 Tomcat Jetty Netty

For most of us, the proper way is to use a well designed web server framework such as Tomcat, Jetty, or Netty


作为练习以更熟悉整个网络事物

as an exercise to get more familiar with this whole web thing

然而,如果这是学习HTTP的学术练习,那么首先要做的是研究HTTP协议(参见 http://www.w3.org/Protocols/rfc2616/rfc2616.html )。我很确定你没有这样做,因为你的代码没有尝试识别起始行,标题等以确定GET请求何时完成并且发送响应是有意义的。

However if this is an academic exercise to learn about HTTP, then the first thing to do is study the HTTP protocol (see http://www.w3.org/Protocols/rfc2616/rfc2616.html). I'm pretty sure you have not done this because you code is making no attempt to identify the start line, headers etc to figure out when the GET request is complete and it make sense to send a response.

[更新]

酷。您已经了解了TCP如何面向流并且不保留消息边界。是的,应用程序必须处理。这是最后一个想法 - 你可能会让你的实验相当可靠 - 只有GET请求才会介意 - 如果你使用 readLine 来读取起始行和标题。当您得到一个空行时,请求就完成了。这将导致缓冲的阅读器在正确的时间阻止,以便您获得所有内容。

Cool. You've learned about how TCP is stream oriented and does not preserve message boundaries. Yes the application has to handle that. Here is a final thought - you could probably get your experiment to work fairly reliably - only for GET requests mind you- if you used readLine to read the start line and headers. When you get a blank line, the request is done. This will cause the buffered reader to block at the right times so you get all your content.

这不适用于POST等,因为您需要解析内容-Length标头并读取一定数量的字节。

This will not work for POST etc because you would then need to parse the Content-Length header and read some number of bytes.

希望这个实验能让你更好地欣赏Jetty,当你意识到正确可靠地做到这一点有多少 - 所以我认为这是值得的努力。

Hopefully this experiment will make you appreciate Jetty more when you realize how much is involved in doing this correctly and reliably - so I think it's a worthwhile effort.

这篇关于听取HTTP请求的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆