TCP:因性恶而复杂,先恶后善反轻松

2019-04-11  本文已影响0人  枯树恋

TCP协议之所以复杂,是因为他认为网络环境是恶劣的,丢包、乱序、重传、拥塞都是常有的事,发出的数据很可能到达不了目标设备,因此需要从算法层面保证其可靠性。

TCP包头格式

TCP包头格式.jpg

源端口和目标端口:保证数据发送给特定的应用。

包的序号:解决乱序问题。

确认序号:解决丢包问题,发送出去的数据一定要有确认,否则应该重新发送直到送达。

状态位:SYN表示发起连接,ACK表示回复,RST是重连,FIN是结束连接。TCP是面向连接的,因此双方会维护连接状态,带有状态为包的发送会引起双方状态的变更。

窗口大小:流量控制,通信双方各声明窗口标识当前处理能力,进而控制发送频率保持在合理范围。拥塞控制:即提出要求又不强人所难。

因此:
顺序问题,稳重不乱;丢包问题,承诺靠谱;连接维护,有始有终;流量控制,把握分寸;拥塞控制,知进知退。

TCP的连接维护

TCP建立连接:三次握手

A: Hello, this is A!

B: Hello, this is B!

A: Hello, B!

通常成为“请求---->应答---->应答之应答”三个回合。

假设网络通路是不可靠的,A发起连接,当第一个请求没有收到回复的时候可能发生:丢包、超时、B没有响应不想建立连接。此时A无法确认结果,于是重发。

终于B收到了A发送的包,但是包到达B这件事A并不知道。A可能继续重发。

B知道A想建立连接,如果B不愿意建立,那么A重试一段时间后放弃,连接建立失败,没有问题。如果B愿意建立连接,则会发送应打包给A。

这个应答包能不能到达A,B一无所知。那么B自然不能认为这个连接建立好了。特殊情况,假设B认为连接成功建立,B收到了A在重试过程中发送的请求包,会误认为是正常的请求,明显不合情理。因此两次握手肯定不行。

B的应答包也会发送多次,但只要有一次到达A,A就认为连接建立,因为A发出的信息有去有回。对于B来说,发出的消息只有收到回复才能确定连接建立,因此需要A发送确认包给B。

因此至少需要三次握手。

三次握手除了建立连接之外,还沟通了一件事情:TCP包的序列问题。A要告知B我发送的包要从那个序列号开始,B同样需要告知A我发的包要从那个序列号开始。每个连接都要有不同的序列号,序列号随时间变化而变化,可以看成是32位计数器,每间隔4ms加1.

TCP三次握手时序图.jpg

TCP四次回收

A: Hello, I will exit.

B: Got it.

B: Hello, I will exit, too.

A: Ok, ByeBye!

TCP四次挥手时序.jpg

A发送即将退出后进入FIN-WAIT-1状态,B收到之后发送给A”知道了“之后进入CLOSE-WAIT状态。

A收到B的回复,进入FIN-WAIt-2状态;此时如果B跑路,A会一直停留在这个状态。

B处理玩自己的事情,发送给A我也要跑路了,A收到之后会给B一个回复表示收到。按说B可以直接跑路了,但是假如B收不到回复的确认信号,会重发给A告知我也要跑路了,如果A直接走了,B就永远也收不到ACK了。因此TCP协议要求A最后等待一段时间TIME-WAIT,这个时间足够长,足以收到B重发的包并回复ACK信号。

A直接跑路还可能存在问题:A的端口空闲并被其他应用占用,那么这个应用汇收到B发过来的包。为了双重保险,要求A等待足够长的时间进而保证B发送的包都消失,再空出端口。等待时间设置为2MSL(Maximum Segment Lifetime,报文最大生存时间),协议规定为2分钟,常用30秒、1分钟、2分钟。

如果B超过了2MSL时间还没有收到ACK,则会重发,会继续发FIN,A收到后表示我已经等了足够长的时间了,你发给我我也不认了,会发送给RST给B,B就知道A已经退出了。

TCP状态机

TCP状态机.jpg

小结

主要关注顺序问题、丢包问题、连接维护、流量控制、拥塞控制。
连接的建立三次握手断开四次挥手。

上一篇 下一篇

猜你喜欢

热点阅读