- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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 )。不过,我想知道如何强制它。
最佳答案
发送一个空的 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/
我是 Java 新手,我遇到了这个我无法解决的问题。我继承了这个项目,并且我的 scriptlet 之一中有以下代码: DefaultLogger.logMessage("DEBUG path: "+
在做web应用的自动化测试时,定位元素是必不可少的,这个过程经常会碰到定位不到元素的情况(报selenium.common.exceptions.NoSuchElementException),一般
我之前已经这样做过,但令我惊讶的是 CListCtrl 不会以颜色显示文本。我在对话框上有 ListView 控件。我正在使用 VS2010,是否还缺少其他东西? void CGameView::On
我正在尝试计算 4 个表中每个学生的 GPA: Student(STUDENT_ID, STUDENT_LNAME, STUDENT_FNAME, MAJOR) Course(COURSE_NO, C
当我在 windows 和 mac 上使用 jasper 报告时它工作正常,当我将我的应用程序部署到 linux 机器 并尝试生成它抛出的报告时 net.sf.jasperreports.engine
我正在构建 iOS 应用并尝试实现应用内购买(非消费品)。 所有 bundle ID 等都已设置并正常工作,当我获取 Apple Store 服务器时,我可以看到我的产品有效。但是,在测试时,我在 p
我正在尝试使用非固定字符数组读取用户输入,但当我在键盘上输入内容时它只是软崩溃(没有崩溃窗口)。当我在在线 C 编译器上运行它时,它说 Segmentation fault (core dumped)
事实: 无根 podman 非常适合 uid 1480 无根 podman 为 uid 2088 失败 中央操作系统 7 内核 3.10.0-1062.1.2.el7.x86_64 podman 版本
根据 homebrew-brew 官方的解释得知,MongoDB 不再是开源的了,并且已经从 Homebrew中移除 #43770 正是由于 MongoDB 的商业化不太理想,所以它选择了闭源。所
我用命令禁用collectstatic heroku config:set DISABLE_COLLECTSTATIC=1 成功将我的项目推送到 Heroku 后,手动 collectstatic 如
代码如下: public class TryStuffOutHere { public static void main(String[] args) {
我已经设置了我的 redis 服务器,以便 CONFIG GET dir --> "/var/lib/redis" 和 CONFIG GET dbfilename --> "redis.rdb". 但
我是一名优秀的程序员,十分优秀!