0

我想创建不应该关闭的保持连接。我尝试了以下方式,但它在打印日期后关闭。

public class SimplePHTTPServer {
  public static void main(String args[]) throws IOException {
    ServerSocket server = new ServerSocket(1122);
    System.out.println("Listening for connection on port 1122 ....");
    while (true) {
      try (Socket socket = server.accept()) {
        Date today = new Date();
        String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
        socket.getOutputStream().write(httpResponse.getBytes("UTF-8"));
        Thread.sleep(5000);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
    }
  }
}

下面通过 curl 测试的是实际输出:

curl -i -X GET -H “连接:保持活动” http://localhost:1122/

HTTP/1.1 200 正常

2018 年 8 月 2 日星期四 18:42:30 IST

预期结果是:

curl -i -X GET -H “连接:保持活动” http://localhost:1122/

HTTP/1.1 200 正常

2018 年 8 月 2 日星期四 18:42:30 IST

2018 年 8 月 2 日星期四 18:47:30 IST

2018 年 8 月 2 日星期四 18:52:30 IST

... 很快

如何创建保持连接?

4

1 回答 1

0

您误解了持久连接的目的。它允许您通过一个连接发出多个请求并获得多个响应。

在您的测试中,您发送一个请求并尝试提供无限长度的响应正文。

您尝试提供无限长度响应正文的方式是不正确的。请阅读此RFC,特别注意“传输编码”。一些选择引用:

HTTP/1.0 中的持久连接是明确协商的,因为它们不是默认行为。HTTP/1.0 的持久连接实验实现存在缺陷,HTTP/1.1 中的新设施旨在纠正这些问题。

...

持久连接是 HTTP/1.1 消息的默认设置;我们引入了一个新的关键字 (Connection: close) 来声明非持久性。请参阅第 14.10 节。

...

7.2.2 实体长度

消息的实体长度是在应用任何传输编码之前消息正文的长度。第 4.4 节定义了如何确定消息体的传输长度。

...

4.4 消息长度

消息的传输长度是消息中出现的消息体的长度;也就是说,在应用了任何传输编码之后。当消息中包含消息正文时,该正文的传输长度由以下之一确定(按优先顺序):

...

2.如果存在 Transfer-Encoding 标头字段(第 14.41 节)并且具有除“identity”以外的任何值,则使用“分块”传输编码(第 3.6 节)定义传输长度,除非消息通过关闭连接终止。

3. 如果存在 Content-Length 头字段(第 14.13 节),则其在 OCTET 中的十进制值表示实体长度和传输长度。如果这两个长度不同(即,如果存在 Transfer-Encoding 头字段),则不得发送 Content-Length 头字段。如果接收到的消息同时带有 Transfer-Encoding 头字段和 Content-Length 头字段,则必须忽略后者。

4.如果消息使用媒体类型“multipart/byteranges”,并且没有另外指定传输长度,则此自限媒体类型定义传输长度。除非发送者知道接收者可以访问它,否则不得使用此媒体类型;来自 1.1 客户端的带有多个字节范围说明符的 Range 标头的请求中存在意味着客户端可以解析 multipart/byteranges 响应。

范围标头可能由不理解 multipart/byteranges 的 1.0 代理转发;在这种情况下,服务器必须使用本节第 1,3 或 5 项中定义的方法来分隔消息。

5.由服务器关闭连接。(关闭连接不能用于指示请求正文的结束,因为这会使服务器无法发回响应。)

于 2018-08-02T17:57:34.557 回答