TCP相关知识
三次握手
客户端回合-第一次握手
- SYN=1 (同步标志, Synchronize)
- seq=x
服务器回合-第二次握手
- SYN=1
- ACK=1 (确认标志, Acknowledgement)
- ack=x+1 (Acknowledgement Number,收到的序号+1,下一个预期的序列编号)
- seq=y
客户端回合-第三次握手
- ACK=1
- ack=y+1
- seq=x+1
注意
- 大写的ACK和SYN是标志位,也就是flag,也就是只有0或1,表示一种状态
- SYN只在前两个握手里存在,是一种建立连接的意愿,双方互相了解对方的意愿之后就不用再发了
- 仅当ACK=1时确认号字段才有效。 当ACK=0时,确认号无效。TCP规定:在连接建立后,所有传送的报文段都必须把ACK置为1
- seq表示一个TCP包的序号,可以看出客户端和服务器各自有自己的序号,这样双方就能知道对方发来的数据的顺序
- 小写的ack为自己确认收到的最后一TCP包的序号+1,告知对方我想要的下一个包的开始是什么
形象一些:
客户端:
SYN=1 ---> 我想要建立TCP连接,请问可以吗
seq=x ---> 这条信息是我发的第x条信息
服务器:
SYN=1 ---> 我同意和你建立TCP连接
ACK=1 ---> 这条信息包含确认信息
ack=x+1 ---> 我收到的你发来的最后一条信息是第x条,下一条信息你应当从x+1开始发
seq=y ---> 这条信息是我发的第y条信息
客户端:
ACK=1 ---> 这条信息包含确认信息
ack=y+1 ---> 我收到的你发来的最后一条信息是第y条,下一条信息你应当从y+1开始发
seq=x+1 ---> 这条信息是我发的第x+1条信息
另外,所谓的握手,我认为是某一方发送的消息到达对方的那一刻称为握手。这表明我发送了消息,你收到了消息,我们两个共同知晓了这条消息,像握手一样。在图中就是箭头到达对方那一刻。
四次挥手
客户端回合-第一次挥手
- FIN=1 (Finish)
- seq=u
服务器回合-第二次挥手
- ACK=1
- ack=u+1
- seq=v
服务器回合-第三次挥手
- FIN=1
- ACK=1
- ack=u+1
- seq=w
客户端回合-第四次挥手
- ACK=1
- ack=w+1
- seq=u+1
注意
- 所谓的服务器和客户端只是一个名字,不论是建立连接还是断开连接,我们都认为率先发起的为客户端,被动接受的为服务器
- 第二和第三次挥手都是服务器回合,服务器首先回复表示收到了数据,然后传送剩余的没传完的数据,然后准备关闭连接
- seq=w和seq=v之间的数据就是剩余的没传完的数据,同时,这两次回复的确认号都是ack=u+1
- 由于客户端发起的关闭连接请求,所以认为他数据已经传输完毕,所以在第二和第三次挥手之间不传输数据
形象一些,就像你妈喊你吃饭,而你在打游戏。
妈妈(客户端) | 你(服务器) | 类比 |
---|---|---|
“吃饭了” | 客户端请求关闭连接 | |
“来了”,但没有动 | 服务器收到关闭连接的请求并回复 | |
赶紧找到游戏的存档点并保存 | 服务器传输剩下的没传完的数据 | |
“来了”,并走向厨房,“今天中午吃什么” | 服务器的第三次挥手,确认关闭连接 | |
“面条。快点吃吧,饭都凉了” | 客户端确认自己收到了服务器的“确认关闭连接” |
中间的两次“来了”都是在确认妈妈第一次喊的“吃饭了”。
那么,基于上面的类比,解释客户端TIME_WAIT状态的意义是什么?
为了防止你没有听到“面条”这个回答。如果你没有听到,你会再问一遍,直到听到答案。
放到网络环境里就是:
第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK(上次自己发的消息没有被确认,他会认为自己的消息丢了,所以重发上次的消息),就会重发FIN,如果Client在2MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。
MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
TCP如何保证有序
(1)为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;
(2)并为每个已发送的数据包启动一个超时定时器;
(3)如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
(4)否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
(5)接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。