从Telnet协议讲起
这个例子来自《计算机网络自顶向下方法》第6版 3.5.2小节。 上图中,因为主机A发送了一个字符C 给主机B,所以作为接收方B的反馈的ACK为42+1。 上图中,因为主机B发送了一个字符C 给主机A,所以作为接收方A的反馈的ACK为79+1。 而在最后一次发送中,由于没有携带任何数据,实际上Seq = 43 是没有意义。但由于这个固定字段总得放个值进去,所以放个Next Sequence Number到这里是最合适的。也就是说这次发送没有消耗掉序号。 有意义的只有ACK = 80 ,这样就告诉了主机B:我这边已经成功接受到了 起码序号为79且长度为1 的数据。
下一次的可能发送情况
如果下一次是主机A再发送数据,数据包的Seq还会是43,因为上一次主机A的发送并没有消耗掉序号(即Len = 0 ),所以主机A发送的数据包序号还是应该从43开始。 如果下一次是主机B再发送数据,数据包的ACK还会是43,因为上一次主机A的发送并没有消耗掉序号(即Len = 0 ),所以主机B还是期待对方从43开始的序号。
三次握手时的ACK
这是本机与百度之间的三次握手。 首先看前两个数据包,第一个数据包的Len = 0 ,但第二个数据包的ACK 还是在Seq = 0 的基础上加1了。这就很奇怪,因为按照上一章的逻辑,没有携带数据,那么ACK 应该等于Seq 的。 再看后两个数据包,同样的,第一个数据包的Len = 0 ,但第二个数据包的ACK 还是在Seq = 0 的基础上加1了。
解释
The server responds to the client with a sequence number of zero, as this is its first packet in this TCP session, and a relative acknowledgement number of 1. The acknowledgement number is set to 1 to indicate the receipt of the client’s SYN flag in packet #1. Notice that the acknowledgement number has been increased by 1 although no payload data has yet been sent by the client. This is because the presence of the SYN or FIN flag in a received packet triggers an increase of 1 in the sequence. (This does not interfere with the accounting of payload data, because packets with the SYN or FIN flag set do not carry a payload.)
简而言之,接收方反馈的ACK 之所以加1,是因为发送方包含了SYN 标志位或FIN 标志位。
也就是说,只要发送方包含了 SYN 标志位或FIN 标志位,即使没有包含数据,接收方也得认为 发送方消耗掉了一个序号。
另外,带有 SYN 标志位或FIN 标志位的报文段(在三次握手和四次挥手中),也是不允许携带数据的。
|