我在中等负载的系统上运行 systat -tcp 命令,并在 5 秒的窗口中看到如下内容:
/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10
Load Average ||||||||||||
TCP Connections TCP Packets
0 connections initiated 21062 total packets sent
153 connections accepted 16291 - data
153 connections established 125 - data (retransmit by dupack)
11 connections dropped 1 - data (retransmit by sack)
0 - in embryonic state 4271 - ack-only
5 - on retransmit timeout 0 - window probes
0 - by keepalive 217 - window updates
0 - from listen queue 0 - urgent data only
148 - control
0 - resends by PMTU discovery
TCP Timers 21057 total packets received
9752 potential rtt updates 13471 - in sequence
12437 - successful 49 - completely duplicate
763 delayed acks sent 11 - with some duplicate data
140 retransmit timeouts 14 - out-of-order
0 persist timeouts 225 - duplicate acks
0 keepalive probes 12535 - acks
0 - timeouts 0 - window probes
80 - window updates
0 - bad checksum
为什么发送的仅确认数比“延迟确认发送数”加上重复数据接收数高得多?除了传入数据(应通过延迟确认计时器)和接收重复数据(立即确认)之外,什么情况会产生仅确认数据包。我猜是保持活动。但是这个盒子没有长寿命的空闲连接。一切都很短暂和激烈。那里还有一个显示为零的保持活动行项目……
我在这里遗漏了有关 tcp 机器的什么信息?
答案1
您似乎认为只有当机器收到重复数据或计时器到期时才应发送仅确认数据包,但我不明白为什么会这样。还有另一种情况,可能比这两种情况更常见、更重要,即确认窗口几乎已满。
如果另一台机器正在向您发送数据流,并且发送了足够多的数据包以接近确认窗口,则本地机器将向其发送确认。在通常情况下,如果没有其他数据要发送,它将发送仅确认数据包。
那么,为什么会有延迟确认?因为我们不想确认客户端发送的每个数据包:这会产生过多的回程流量。
假设接收窗口允许 10 个传入数据包。远程机器向我们发送一个。无需立即确认,因为他们知道最多可以再向我们发送 9 个。如果他们确实继续发送数据包,那么当我们接近填满窗口时,我们将确认他们的传输。
另一方面,如果他们只向我们发送一个数据包,然后停止一会儿,我们至少要确认我们收到了那个数据包,以便他们知道不要重新传输它,并且他们知道窗口的当前状态。
延迟确认计时器区分这两种情况:如果它们发送大量数据,则让它们继续发送,而不会让数据长时间得不到确认。