【问题标题】:springboot use http respose header transfer:encoding, but tcp send two packet even if the response is smallspring boot使用http响应头传输:编码,但是tcp发送两个数据包即使响应很小
【发布时间】:2021-12-04 05:48:24
【问题描述】:
@SpringBootApplication
@RestController
public class HttpChunkedApplication {

    public static void main(String[] args) {
        SpringApplication.run(HttpChunkedApplication.class, args);
    }

    @PostMapping("/home/getMsg")
    public ChunkedRsp login( HttpServletResponse response ){
        return new ChunkedRsp("aaa","bbb","ccc");
    }
}
@Data
public class ChunkedRsp {
   private String A;
   private String B;
   private String C;

    public ChunkedRsp(String a, String b, String c) {
        A = a;
        B = b;
        C = c;
    }
}

运行应用程序,然后

  1. sudo tcpdump -i any -nnAls0 端口 8080
  2. curl -X POST http://0.0.0.0:8080/home/getMsg

tcpdump 显示两个数据包: tcp dump packet when I curl

【问题讨论】:

标签: spring-boot http tomcat tcp http-headers


【解决方案1】:

您所描述的正是分块编码应该如何工作(参见例如Wikipedia):

  • 每个块都以它的长度(十六进制)和\r\n为前缀,
  • 序列0\r\n\r\n表示消息结束。

发送的 TCP 段数取决于您的 TCP/IP 堆栈(操作系统)。如果连接TCP_NO_DELAY选项为false,则段将合并:参见this question

Tomcat 默认将套接字上的TCP_NO_DELAY 选项设置为true(参见documentation)。要禁用它,请修改您的连接器配置:

<Connector port="8080"
           socket.tcpNoDelay="false"
           ... />

并在真实连接上测试您的服务器(不是环回设备127.0.0.1,它非常快)。

【讨论】:

  • springboot 在返回对象时会使用分块响应。如果返回一个字符串,则响应不会被分块。
  • 是的,确实如此。所以你的问题不是两个 TCP 段,而是 Spring Boot 使用分块编码的事实?你应该通过修改你的问题来澄清它。
  • 为什么分块响应会发送两个 TCP 段?我发现 outputStream.flush() 会发送两个 TCP 段,但 outputStream.write() 会将两个 TCP 段合并为一个。
猜你喜欢
  • 1970-01-01
  • 2020-06-23
  • 2020-12-23
  • 1970-01-01
  • 1970-01-01
  • 2015-04-23
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
相关资源
最近更新 更多