[TOC]
前言
- TCP是一种端对端的协议;
- TCP是无状态协议;
一、TCP的三次握手-连接
1.1 图解流程
- SYN,同步标志位,用于建立连接时,同步自己序列号给对方。
- ACK,确认标志位,当需要发送ack(确认序列号)时,必须置位1。
- seq,数据序列号,表名此次请求发送的第一个数据的序列号为多少,首次自定。
- ack,下次数据的序列号,告诉对方下次应该发过来的第一个数据的序列号应该是多少。
- established,连接已建立。
TCP三次握手实质上就是维护双方 seq(数据序列号) 的过程。
注意:
- SYN报文段不携带数据,但是要消耗一个序号;
- ACK报文段可以携带数据,如果不携带,则下次序列号不变,所以最后一次握手后,下次连接序列号还是从K+1开始;
图解:
- A呼叫B,这是条同步连接,此次数据由J开始;
- B收到;
- B呼叫A,收到同步连接,下次请从J+1开始发送数据,并且同样需要同步,此次数据由K开始;
- A收到,建立连接;
- A呼叫B,收到同步连接,那下次请从K开始发送数据吧;
1.2 为什么不能是四次握手?
其实可以看到,握手的第二次可以拆成两部分完成,先发送ACK,在同步SYN,这样下来就是四次握手了。为什么不呢?因为效果一样,没必要呀~。同样不五次、六次、七次等等原因都是如此。
1.3 为什么不能是两次握手?
这主要是为了防止 已失效的连接请求报文段 突然又传送到了对方,因而产生错误。
已失效的连接请求报文段:第一次握手发送因网络拥堵或其他原因而未到达对方手中。
如果是两次握手,会发生的错误是什么?
两次握手的话,B的established(连接建立)将发生在第一次握手后。
- 如果A第一次发送连接请求(seq=J),因为网络拥堵而为到达B手中,之后发送第二次连接请求后,成功到达,双方后续连接好连接,并开始持续发送数据(A发送给B的seq已经到了N)。
- 此时第一次连接请求到达B,B认为A需要重新建立连接(因为TCP是无状态的,所以只能这么机械认为),然后B建立连接,发送确认、同步请求给A之后,等待接收A数据序号为J+1的数据。
- A收到来自B的确认、同步请求,但A此时已经和B连接,所以忽略此次确认请求,继续发送序列号为N+1的数据。
- B收到序列号为N+1的数据,并不是J+1的数据,不进行接收。
- A没有等到B的回复,一直在超时重传,多次后便报出错误,等待重新连接。
为什么三次握手,不会出现” 已失效的连接请求报文段 突然又传送到了对方,因而产生错误“的情况?
因为B建立连接在第三次握手之后,已失效的连接请求报文段 突然又传送到了对方,并不会改变B下次接收A的数据的序列号(两次握手失败的主要原因:B下次接收A的数据序列号从N+1变成了J+1)。所以在A忽略之后继续发送N+1的序列号数据时,B能正常接收。
第二次或第三次握手拥堵之后,突然又传回对方手中,会产生怎么样的结果?
因为第二次握手和第三次握手都需要有前景,即第一次握手(第二次握手的前景)和第一、二次握手(第三次握手的前景),因为没有前景,所以自然会被忽略掉。
二、TCP的四次挥手-释放
2.1 图解
- FIN,连接结束标志位,表示发送方请求断开连接。
- MSL,最长报文段寿命,约为2分钟,随着时代进步,之后继续变短。
- 2MSL,2个MSL时间,为一个等待计时器的时长。
注意:
- FIN标志位为1时,即使请求不携带数据,也要消耗一个序号。
图解:
- A想关闭连接,并处理好关闭连接的事后;
- A呼叫B,这是条关闭请求,此次序号为u;
- B收到A的关闭请求,同时向应用汇报,关闭连接的事;
- B呼叫A,这是条确认请求,此次数据序号为v,下次发送数据从u+1开始(这表明B收到A的上一条(u)请求了);
- B处理关闭连接的事,同时把需要发送的数据给发送完(此时发送的数据都要保留ack=u+1,因为要给后续A发送用),发送完之后,便进行关闭操作;
- B呼叫A,这是条关闭请求,此次序号为w,下次发送数据从u+1开始;
- A呼叫B,这是条确认请求,此次序号为u+1,下次发送数据从w+1开始;
- A等待2MSL后,关闭连接;
2.2 为什么最后A需要等待2MSL时间呢?
- 保证A最后发给B的报文段能到达B。如果不能到达B,在这2MSL时间段内,完全够B超时重发FIN报文段,且A让收到。如果A收到后,将继续发送最后一次挥手,且重置等待计时器。等待计时器重置也有次数,如果重置多次的话,A将直接关闭。
- 防止”已失效的连接请求报文段“出现在挥手阶段。在这2MSL时间段内,足够让B接收到之前的因网络拥堵而未到达的报文段了,当然报文段有有效时长,超过这个有效时长,将会被丢弃。这样就不会因为下次建立连接时接收到上次建立连接时的报文段而产生错误。
2.3 如果A掉电退出了怎么办?
TCP有一个保活计时器,当双方接收到对方报文段时,保活计时器将重置。如果保活计时器时间结束,它将会主动关闭TCP连接。
三、总结
整个TCP连接、互相发送数据(你向我发送数据,我回复你收到)、挥手阶段,都是一个 维护序号的过程。这个序号就是我同对方讲的这句话的唯一标识符。
seq、ack都尤为重要。seq 表示了某一方数据的唯一性;ack 不仅告诉对方下次应该从哪个位置发送,还能验证对方发送的数据是否正确。
整个通信都是针对双方的,没有哪一方为数据的领导者。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。