【问题标题】:How to make sure that you have read the "full message" when using "Transfer-Encoding:chunked" http response使用“Transfer-Encoding:chunked”http响应时如何确保您已阅读“完整消息”
【发布时间】:2015-10-23 13:09:58
【问题描述】:

我正在使用 HttpUrlConnection (java) 来读取 http 分块响应 (Transfer-Encoding:chunked),如下所示,我能够读取消息。但是,我怎样才能确保我已经正确读取了所有块并且读取的消息是完整的..

BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

【问题讨论】:

    标签: httpurlconnection chunked


    【解决方案1】:

    您好,很抱歉回复晚了,但正如您可能猜到的那样,我只是遇到了您的问题。

    您似乎对分块传输编码的含义有一个小小的误解。 这并不意味着消息将以 CRLF 结尾的行发送。这似乎是您要实现的,但比这要复杂一些。

    如果您不熟悉 CRLF 是什么,它只是表示回车换行(或传统 Unix 转义序列中的 \r\n)。

    分块传输编码意味着消息将按而不是行发送。每个块的格式比以 CRLF 结尾的行更易于解释。

    块的工作原理

    每个块都以 [0-9, 'a'-'f'] 范围内的一系列字符开始。这是一个十六进制数,表示块的长度(以字节为单位)。此十六进制数后跟一个 CRLF。接下来是块数据(希望具有指定的长度)。块数据将以另一个 CRLF 结束。

    您将按顺序获得其中的几个块,并且按照它们到达的顺序将它们连接起来是您的工作。您按顺序阅读它们,直到您获得一个表示消息正文结束的特殊块。最后一个块的唯一特别之处在于它的长度为零并且不包含任何数据,即该块将是0\r\n\r\n

    不幸的是Java的HttpURLConnection类只实现了自动分块传输编码,你必须自己去解码。

    尽管它可能很麻烦,但如果您实施此协议,您可以确信您是否已阅读整条消息...有一个警告...

    您可能需要寻找预告片

    Trailers 与 headers 相同,只是它们出现在 HTTP 消息的 end 中,而 headers 出现在开头。分块传输编码可让您找到消息正文的结尾,但完整的 HTTP 消息可能会继续。

    HttpURLConnection 类不会为您解析预告片。 该类在将其套接字(或它使用的任何东西)定向到连接的 OutputStream 之前解析 HTTP 头(状态行和头)。一旦套接字指向该 OutputStream,它就不会返回。从那时起,由您来处理数据。

    幸运的是,预告片比标题更可预测......或者至少它们应该是。服务器将发送的每个预告片都应该在Trailers 标头字段中的分号分隔列表中指定,即标头中的Trailers: Content-disposition; Cache-control; From 意味着您应该查找Content-dispositionCache-controlFrom 预告片字段在消息之后。

    只允许在分块编码消息中使用尾标,并且它们遵循与标头相同的格式:字段名称、冒号、空格、字段值、CRLF。就像标题一样,如果一个预告片后面跟着两个 CRLF 而不是一个,这意味着它是最后一个预告片。

    【讨论】:

      猜你喜欢
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多