【问题标题】:BufferedReader is not reading body of requestBufferedReader 未读取请求正文
【发布时间】:2018-08-04 04:20:32
【问题描述】:

我正在尝试从 HttpPost 读取数据,但是当我从 BufferedReader 读取数据时,我只能获得标题信息。请看下面的代码。

这是服务器

try {
        ServerSocket server = new ServerSocket(8332);
        System.out.println("Listening for connection on port 8332 ....");
        while (true) {
            try (Socket socket = server.accept()) {
                BufferedReader buffer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String request = "";
                String line;
                while ((line = buffer.readLine()) != null) {
                    System.out.println(line);
                    request += line;
                }

                System.out.print("port 8332 reading: " + request);

            } catch (IOException e) {
                System.out.print(e.getMessage());
            }
        }
    } catch (IOException e){
        System.out.print(e.getMessage());
    }

这里是客户端

    HttpClient client = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost("http://localhost:8332");

    try {
        StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
        post.addHeader("content-type", "application/x-www-form-urlencoded");
        post.setEntity(params);

        client.execute(post);
    } catch (IOException e){
        System.out.println(e);
    }

当我运行这个程序时,我只会得到以下输出

Listening for connection on port 8332 ....
POST / HTTP/1.1
content-type: application/x-www-form-urlencoded
Content-Length: 37
Host: localhost:8332
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.6 (Java/1.8.0_131)
Accept-Encoding: gzip,deflate

在调试时,程序似乎没有退出这个 while 循环

while ((line = buffer.readLine()) != null) {
                System.out.println(line);
                request += line;
            }

但我不知道为什么。请帮助我一整天都被卡住了。

提前致谢

【问题讨论】:

    标签: java server client bufferedreader


    【解决方案1】:

    但我不知道为什么。

    服务器从buffer.readLine() 获得null 的唯一方法是客户端关闭其套接字输出流。

    问题是客户端试图保持连接活动......这意味着它不会关闭其套接字输出流。这意味着服务器需要尊重“内容长度”标头;即计算读取的字节数,而不是寻找流的结尾。

    从根本上说,您的服务器端没有正确实现 HTTP 1.1 规范。

    怎么办?

    我的建议是不要尝试从套接字开始实现HTTP。使用现有框架...或 Apache HttpComponents 库。

    但如果您坚持这样做1,请在开始尝试实施之前彻底阅读 HTTP 规范。 每当您在实施中遇到问题时,请查阅规范,以检查您是否在做正确的事情。


    1 - 定义:受虐狂 - 享受看似痛苦或乏味的活动。

    【讨论】:

      【解决方案2】:

      在您的 while 循环中使用 !=0 而不是 !=null:

      while((line = buffer.readLine()).length() !=0) {
      

      输出:

      端口 8332 读取:POST / HTTP/1.1 内容类型: 应用程序/x-www-form-urlencodedContent-Length: 18Host: 本地主机:8332连接:保持活动用户代理: Apache-HttpClient/4.5.3 (Java/1.8.0_171)接受编码: gzip,deflateorg.apache.http.NoHttpResponseException:本地主机:8332 没有回应

      【讨论】:

      • 1) 当readLine() 返回null ... 这是可以做到的... 你的代码将抛出一个NPE。 2)你不想停在第一个空行。 (在请求标头之后会有一个,在内容中间可能一个。阅读 HTTP 规范。)
      猜你喜欢
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      • 2015-10-02
      • 2017-11-25
      • 2019-01-17
      • 2018-07-06
      • 2020-05-16
      相关资源
      最近更新 更多