【问题标题】:Multiple get requests in a http requesthttp请求中有多个get请求
【发布时间】:2019-06-08 23:12:09
【问题描述】:

在查看客户端->服务器交互以获取图像时,我看到来自客户端的以下 HTTP GET 请求,其中数据包包含 2 个 HTTP GET 请求,我不确定服务器将如何响应此类请求?

  1. 服务器会忽略第二个 GET 请求吗?
  2. 服务器会一一发送响应给每个 GET 请求吗?
  3. 这似乎不是 HTTP 流水线。如果是请告知。

    传输控制协议,Src Port:59649(59649),Dst Port:8080(8080),Seq:1,Ack:1,Len:648 源端口:59649 目的端口:8080 [流指数:86] [TCP 段长度:648] 序号:1(相对序号) 【下一个序号:649(相对序号)】 确认号:1(相对确认号) 标头长度:32 字节 标志:0x018(PSH,ACK) 000. .... .... = 保留:未设置 ...0 .... .... = 随机数:未设置 .... 0... .... = 减少拥塞窗口 (CWR):未设置 .... .0.. .... = ECN-Echo:未设置 .... ..0。 .... = 紧急:未设置 .... ...1 .... = 确认:设置 .... .... 1... = 推:设置 .... .... .0.. = 重置:未设置 .... .... ..0。 = 同步:未设置 .... .... ...0 = Fin:未设置 [TCP 标志:*******AP***] 窗口大小值:683 [计算窗口大小:43712] [窗口大小缩放因子:64] 校验和:[验证禁用] [良好的校验和:错误] [错误校验和:错误] 紧急指针:0 选项:(12 字节)、无操作 (NOP)、无操作 (NOP)、时间戳 无操作 (NOP) 类型:1 0... .... = 碎片复制:否 .00。 .... = 类别:控制 (0) ...0 0001 = 编号:无操作 (NOP) (1) 无操作 (NOP) 类型:1 0... .... = 碎片复制:否 .00。 .... = 类别:控制 (0) ...0 0001 = 编号:无操作 (NOP) (1) 时间戳:TSval 6345、TSecr 6344 种类:时间戳选项 (8) 长度:10 时间戳值:6345 时间戳回显回复:6344 【SEQ/ACK分析】 [iRTT:0.000099000 秒] [飞行中的字节数:648] 超文本传输​​协议 获取 HTTP/1.1\r\n [专家信息(聊天/序列):GET HTTP/1.1\r\n] [获取 HTTP/1.1\r\n] [严重级别:聊天] [组:序列]在此输入代码 请求方法:GET 请求 URI: 请求版本:HTTP/1.1 主机:\r\n 已发送:\r\n 用户代理: \r\n 接受编码: gzip, deflate\r\n 接受语言: en-GB,*\r\n 连接: 保持活动\r\n \r\n [完整请求 URI:] [HTTP 请求 2/2] [帧中的上一个请求:1254] [帧内响应:1272] 超文本传输​​协议 获取 \r\n [专家信息(聊天/序列):GET HTTP/1.1\r\n] [获取 HTTP/1.1\r\n] [严重级别:聊天] [组:序列] 请求方法:GET 请求 URI: 请求版本:HTTP/1.1 主机:\r\n 已发送:\r\n 用户代理: \r\n 接受编码: gzip, deflate\r\n 接受语言: en-GB,*\r\n 连接: 保持活动\r\n \r\n [完整请求 URI:] [HTTP 请求 2/2] [帧中的上一个请求:1254] [帧内响应:1272]

我可以使用任何在线工具来测试此类请求吗?

【问题讨论】:

    标签: http tcp pipelining


    【解决方案1】:

    如果合适的话,将多个 HTTP 请求放在一个 TCP 数据包中是完全可以接受的。

    您所看到的确实是 HTTP 管道,它在 HTTP 1.1 规范的 RFC 2616 Section 8RFC 7230 Section 6.3.2 中有所介绍。客户端正在发送一个新的GET 请求,而无需先等待对先前GET 请求的响应。这就是流水线的定义:

    HTTP 请求和响应可以在连接上进行管道传输。 流水线允许客户端发出多个请求而无需等待每个响应,从而可以更有效地使用单个 TCP 连接,并且花费的时间要短得多。

    TCP 只是通过对两个 HTTP 请求使用单个 TCP 数据包来优化事物。客户端可能启用了send coalescing(又称“Nagle 算法”)(大多数套接字库默认启用)以减少网络流量。

    为了让服务器响应流水线请求,必须使用持久连接,这是流水线的另一个要求,并且在您的示例中清晰可见(Connection: keep-alive 请求标头)。

    TCP 是一个字节流,较低级别的 TCP 帧与较高级别的协议层无关。 正确编写的 HTTP 接收器将能够分离单独的 HTTP 消息,而不管使用的 TCP 帧,并根据需要单独处理它们。 HTTP 1.1 规范要求所有请求的响应顺序与接收到的顺序相同(HTTP 2.0 改变了这一点,但这是一个更复杂的处理过程 - 多路复用 - 我不会深入探讨)。

    所以,回答你的问题:

    1. 服务器会忽略第二个 GET 请求吗? - 否

    2. 服务器会一一发送响应给每个 GET 请求吗? - 是的

    3. 这似乎不是 HTTP 流水线。如果是,请告知。 - 是的,但不是因为你想的原因。

    【讨论】:

    • 谢谢雷米,这真的很有帮助。但是如果客户端发送 2 个连接的 http 请求,服务器根本看不到第二个 http 请求。我正在使用 lighttpd 进行实验,它支持流水线。背后的原因可能是什么?
    • @MuralitharanPerumal 我无法回答。您将不得不向 lighttpd 作者询问。听起来像是该软件中的逻辑错误。我有自己的 http 服务器实现,它可以很好地处理串联的流水线请求。
    • 感谢您的快速回复。您能否分享任何实现串联请求的参考代码?
    • 我正在查看 lighttpd 代码 (connections.c) github.com/lighttpd/lighttpd1.4/blob/master/src/… [我们读取整个请求,即在这种情况下连接的 http 请求] 和 github.com/lighttpd/lighttpd1.4/blob/master/src/… [我们只读取一个标头]。我是不是错过了什么。任何输入都会有所帮助。
    • ALL 基于 TCP 的软件必须处理 TCP 只是一个字节流并且没有消息传递概念的事实。 TCP 数据包包含任意数据。更高级别的协议定义了它们的消息的样子。单个 TCP 数据包可能包含(一条)单个消息,也可能包含(条)多个消息。可能需要多个 TCP 数据包才能完成一条完整的消息。接收者的工作是缓冲原始数据并根据消息的结构将消息重新组合在一起。而且 HTTP 有一个非常明确的消息结构。
    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多