gpt4 book ai didi

sockets - 为什么HTTP客户端在三次握手的ACK报文中发送空数据?

转载 作者:行者123 更新时间:2023-12-03 11:51:00 25 4
gpt4 key购买 nike

我正在使用 Wireshark,我注意到我的浏览器连接了一个网站,它发送了一个空的 ACK 数据包(而不是带有 http 请求的 ACK 数据包)。为什么会这样?在 TCP 和 HTTP RFC 中,不禁止发送带有数据的 ACK 数据包。这里可以实现延迟ACK吗?

另外,有没有办法在套接字编程中启用/禁用发送带有数据的 ACK?

注意:似乎可以将 ACK 数据包与数据一起发送(参见 https://osqa-ask.wireshark.org/questions/36023/tcp-3-way-handshake-data-in-third-message )。不过,我想知道如何强制它。 enter image description here

最佳答案

发送一个空的 ACK 作为 TCP 握手的一部分实际上比已经在 TCP 握手的最后部分包含数据更常见。

典型的客户端代码首先调用 connect,只有在它成功返回后才会发送数据。 connect 仅当服务器以 SYN+ACK 响应时才会成功返回。内核将为此自动发出 ACK 以向服务器发出握手现已完成的信号。内核此时没有任何应用程序数据要发送,因此它不能将这些数据包含到此 ACK 中。

试想一下,如果最终的 ACK 被推迟以等待来自客户端的更多潜在数据会发生什么:在最坏的情况下,客户端不会发送此类数据,因为它首先等待来自服务器的数据 - 这是典型的SMTP、FTP 等协议(protocol)...。但是由于服务器没有从客户端获得 ACK,它不会认为 TCP 握手完成,因此不会发送任何数据。因此,这将引入不必要的延迟,直到客户端决定发送空 ACK 为止。

因此,为了优化握手,客户端必须告诉内核它将立即开始发送数据并且内核不应该已经发送它的 ACK。这至少可以在 Linux 中使用 TCP_QUICKACK 选项来完成:

import socket
s = socket.socket()
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, False)
s.connect(("example.com",80))
s.send(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
print(s.recv(1024))

TCP_QUICKACK 显式设置为 False 时,TCP 握手的 ACK 已经传输了应用程序数据:

IP local-system.45664 > example.com.http: Flags [S], seq 1590101890, win 29200, options [mss 1460,sackOK,TS val 4226937632 ecr 0,nop,wscale 7], length 0
IP example.com.http > local-system.45664: Flags [S.], seq 3649111496, ack 1590101891, win 65535, options [mss 1452,sackOK,TS val 625701214 ecr 4226937632,nop,wscale 9], length 0
IP local-system.45664 > example.com.http: Flags [P.], seq 1:38, ack 1, win 229, options [nop,nop,TS val 4226937765 ecr 625701214], length 37: HTTP: GET / HTTP/1.0

没有显式设置选项得到空 ACK:

IP local-system.45856 > example.com.http: Flags [S], seq 4147534093, win 29200, options [mss 1460,sackOK,TS val 4227186296 ecr 0,nop,wscale 7], length 0
IP example.com.http > local-system.45856: Flags [S.], seq 123501506, ack 4147534094, win 65535, options [mss 1452,sackOK,TS val 2369778695 ecr 4227186296,nop,wscale 9], length 0
IP local-system.45856 > example.com.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 4227186421 ecr 2369778695], length 0
IP local-system.45856 > example.com.http: Flags [P.], seq 1:38, ack 1, win 229, options [nop,nop,TS val 4227186421 ecr 2369778695], length 37: HTTP: GET / HTTP/1.0

关于sockets - 为什么HTTP客户端在三次握手的ACK报文中发送空数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59700593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com