假如一个tcp程序A向另一个TCP程序B发送两个数据包,数据包1:序列号从1000到2000;数据包2:序列号从2000到3000。
通常B应该回复2个ACK,一个用于确认数据包1,另一个用于确认数据包2。现在,如果A只收到第二个ACK,A是否还会等待第一个ACK?
我知道TCP是面向字节的流协议。所以A不应该等待第一个ACK,对吗?理论上是这样的,那么实际实现的TCP协议栈是怎样的呢?
顺便说一句,我有一个奇怪的问题。如果 A 向 B 发送一个 ACK,其 ACK 序列号为 3001(这是用于确认数据包 2)。但中间有人将 ACK 序列号修改为 2501,也就是说,B 确认了一个半 TCP 数据包。那么 A 会从对应于序列 2000 或 2501 的字节重新传输吗?
答案1
不是,TCP 采用“滑动窗口”机制来减少所需的确认次数。
一个很好的可视化和解释:http://histrory.visualland.net/tcp_swnd.html
答案2
TCP 将确认序列号,而不是数据包。因此,即使没有“中间人”,程序 A 也只能确认收到的数据包的一小部分(即套接字没有足够的缓冲区空间容纳所有数据包)。在您的示例中,程序 B 将重新传输 2501。
TCP 还支持选择性确认,因此只需要传输缺失的段(在序列号空间中)
答案3
乙提供一个缓冲空间的“窗口”来A在其承认中。A在发送后续数据包之前无需等待特定确认,只要它不超过乙的当前窗口。
警告:为了简洁起见,也因为我对该协议的理解有限,所以进行了大大的简化。RFC:813 - TCP 中的窗口和确认策略谈论的就是这种技术。