TCP报文结构、确认应答机制、超时重传机制、连接管理机制
一、TCP报文结构
可靠传输是TCP中最最核心的特性!!!
上篇博客我们已经介绍过了UDP报文结构:UDP的报文结构和注意事项
而TCP的报文结构更为复杂:(实际上仍然是依次顺序排列的)
二、确认应答机制
拿"我"和"女神"来举例子~~
回复的"好啊好啊"就是"确认报文",也称为ACK报文 ack => acknowledge (应答)
而有时可能会出现"后发先至"的情况:
一旦出现这个情况,"我"的理解就出现差异了!
解决方案:针对请求和应答报文进行编号~
TCP是字节流的协议,编号的时候也是以字节为单位进行编号的!
TCP将每个字节的数据都进行了编号,即为序列号。
每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。
确认应答机制,就是TCP保证可靠性的最核心机制!!!
三、超时重传机制
确认应答机制描述的是数据报顺利到达对方,对方给了个响应。但是传输过程中可能会丢包,如果丢包又该如何?
为啥会"丢包"?
网络环境是非常复杂的,我能上网是因为我接入了运营商的网络。运营商这边就有很多很多的路由器/交换机,共同组建出一个非常庞大复杂的网络。某个交换机上面,不光是传输我的数据报,也在传输别人的数据报。
某个时刻,很多很多数据报都经过这个交换机,而交换机的转发能力不是无限的 (有上限),很多数据报都走这里导致达到交换机的转发上限,无法快捷地完成转发了,就可能会导致有一部分数据报就超时了!!!
就和大城市经常会堵车一样~~
过了一会,我这里仍然等不到女神的回复,我就认为之前发的消息丢了!于是我就重新再发一遍!!
站在概率论的角度来看:
假设单个报文丢包的概率是10% (极大的数字了),则连续两个报文丢包的概率为10%×10%=1%;假设单个报文丢包的概率是1%,连续两个报文丢包的概率0.01×0.01=0.0001,即万分之一 ~~
当然也可能是ACK丢包了:
站在发送者的角度,"我"只是没收到ACK,但无法区分是我发的数据丢了,还是ACK丢了,所以二者都需要进行重传!!!
但如果是ACK丢包了,此时重传后,接收方会收到两条重复的消息?
NO!TCP会针对相同的消息进行去重 (根据序号来去重即可)!! 保证了应用层代码通过socket读取数据的时候,读到的不是重复数据~~
四、连接管理机制
在正常情况下,TCP要经过三次握手 (本来是4次,但中间两次可以合并在一起) 建立连接,四次挥手断开连接!!
4.1 三次握手建立连接
通信双方,各自向对方申请,尝试和对方建立连接然后再各自给对方回应~~
建立连接的过程其实是四次的数据交互!
为啥要建立连接?建立连接的意义是什么??
- 投石问路。检查一下当前网络情况是否畅通!
三次握手建立连接并不传输任何业务数据~~ - 检查通信双方的发送能力和接收能力是否都是正常的。
举个例子:
- 三次握手过程中,也是在协商一些重要的参数。
举个例子,TCP的序号并非是从1开始的,通常都是建立连接的时候协商了一个数字。目的是保证两个连接的序号有差别!如果连接断开又快速重连,接收方就可以区分当前收到的数据是当前连接的还是上个连接的~~
4.2 四次挥手断开连接
通信双方各自向对方申请断开连接,再各自给对方回应。
ACK:确认报文段;
SYN:同步报文段;
FIN:结束报文段。
所以一般情况下断开连接不会合并为三次~~ (但TCP还有一个捎带应答机制,若触发可能合并为三次)
TIME_WAIT状态产生的原因可以总结为:
1)为实现TCP全双工连接的可靠释放;
2)为使旧的数据包在网络因过期而消失。