目录
TCP特点:
1.有连接
2.可靠传输
3.面相字节流
4.全双工
而可靠传输是TCP的初心,也是最核心的机制
这里的可靠传输,不是说100%的传过去(很难实现)
而是尽可能的传过去,如果没有传送过去,发送方至少能自动自己没传过去
核心机制在于:接收方收到了或者没收到会有个应答
一.确认应答
实现可靠性的最核心机制:
应答报文:ACK报文(acknowledge)
接受方在确认收到数据后会回复一个ACK
你要知道,在网络上的信息传输过程中,你先发的信息不一定就先到,因为期间要经过很多个节点,这里就可能会有后发先至的情况;
所以TCP将每个字节的数据都进行了编号.即为序列号
接收方收到到了1-1000的序列号,知道接下来就应该收到的是1001开头的信息了
而如果出现了后发先至的情况,TCP就会承担起整队的任务
TCP会有一个接受缓冲区(一块内核中的内存空间)
TCP就可以按照序号针对收到的信息进行整队
TCP结构:
接收方可以通过ack的确认序号,告诉发送方哪些数据已经收到了
二.超时重传
丢包,也是网络上非常典型的情况
为啥会丢包呢?
在我们数据传输的过程中,是要经过很多节点来传输,如果中间任何一个节点出现了问题,都可能会导致丢包
每个设备的转发能力都是有上限的
某一时刻,某个设备上面的流量达到峰值,就可能会引发部分数据被丢包
如果包丢了,接收方就收不到了,自然就不会返回ack
发送方就迟迟的拿不到应答报文
等待一段时间之后,还是没有收到应答报文 ,发送方就视为刚才的数据丢包了
就会重新再发一遍
发送方对于丢包的判定,是一定时间内没有收到ack
1.数据直接丢了,接收方没收到,自然不会发ack
2.接收方收到数据了,返回的ack丢了
发送方是区分不了这两种情况的,只能都重传
三 连接管理
TCP建立连接:三次握手
TCP断开连接:四次挥手
这个和可靠性有一点的关系,但不是绝对性的因素,一般面试官问可靠性一般回答确认应答和超时重传
三次握手:
握手指的是通信双方,进行一次网络交互
相当于客户端和服务器之间,通过三次交互,建立了连接关系(双方各自记录对方的信息)
上述过程是内核自动完成的,应用程序干预不了
等到连接完成了,服务器accept把建立好的连接从内核拿到应用程序中
syn称为同步报文段
意思就是一方要向另一方申请建立连接
三次握手完成,连接建立就完成了
为啥要进行三次握手?
三次握手本质上就是投石问路,验证了客户端和服务器各自的发送能力和接受能力是否正常
四次挥手
断开连接,四次挥手(和三次握手非常像)
通信双方,各自给对方发送一个FIN(结束报文),再各自对对方返回ACK
为什么握手是三次,而挥手是四次呢?
三次握手,ack和syn是同一个时机触发的(都是内核来完成的)
四次挥手,ack和fin则是不同时机触发的
ack是由内核完成,会在收到fin的时候第一时间返回
fin则是应用程序代码控制的,在调用socket的close方法的时候才会触发fin
在服务器发现客户端断开连接后,自己也会执行close操作,这个close操作触发了第二个fin
四 滑动窗口
批量传输,叫做滑动窗口
批量不是无限发送,是发送到一定程度,就等待ack,不等待直接发送的数据量是有上限的
而且是回来一个ack就立即发下一条,相当与总的要批量等待的数据是一致的.
把批量等待数据的数量,就称为"窗口大小"
如果批量发送的过程中,出现了丢包:
这个图中的丢包率已经非常严重了,但是即使丢了这么多ack对于可靠性还是没有任何的影响
确认序号的含义就是表示该序号之前的数据都已经收到了.
后一个ack能够覆盖前一个ack的意思
当收到2001这个ack的时候,发送方就知道2001之前的数据都收到了
即使前面的ack全部丢了也无所谓
当1001这个数据重传过来之后,此时缺失的拼图就补全了
接下来就要从7001开始索要
如果是4001也没有,在收到1001-2000之后
接下来返回的ack就是索要4001,反复索要多次发送方就会重传4001
上述重传过程整体速度是比较快的,这个过程也叫快速重传
滑动窗口,快速重传是在批量传输大量数据的时候会采取的措施
如果只是传输少量的低频的操作,就是用前面的确认应答和超时重传了
五 流量控制
滑动窗口是用来批量发送的,
窗口越大,相当于批量的数据越多,整体的速度就越快
但是如果太快了就直接把接收方缓冲区给打满了,接下来发送数据就会丢包
通过流量控制来限制发送方的速度
具体如何来控制:
在ack的报文中,携带一个"窗口大小"这样的字段
六 拥塞控制
滑动窗口的大小取决于流量控制和拥塞控制
流量控制:衡量了接收方的处理能力
拥塞控制:衡量了传输路径的处理能力
拥塞控制做的事情就是衡量中间节点的传输能力
通过实验的方式找到一个合适的发送速率:
开始的时候,按照一个小的速率发送,如果不丢包,就可以提高一下速率(扩大窗口的大小)
如果出现丢包,就把速率在调小
一直重复上述过程
因为网络的拥堵情况是时刻变化的,拥塞控制就能很好的适应变化的网络环境
七 延时应答
TCP可靠的核心是确认应答
但ACK的发送会延迟一些再发
TCP中决定传输效率的关键元素是窗口大小
而窗口大小的有一个决定性因素就是接收方的接受缓冲区的剩余空间大小
延时应答的效果就是通过这个延时,让接收方应用程序趁机多消费点数据,此时反馈的窗口大小就会更大一些,此时发送方的发送速率也就能更快一些
八 捎带应答
基于延时应答
客户端服务器之间的通信模型,通常都是"一问一答"这种模式
客户端服务器通信模型:
1.一问一答:绝大部分服务器
2.多问一达:上传大文件
3.一问多答:下载大文件
4.多问多答:游戏串流
九.面向字节流
面相字节流这里暗藏了一个杀机:
就是粘包问题:
"一句话"就相当于一个"应用层数据报"
当A给B连续发了多个应用层数据报之后,这些数据就能积累到B的接受缓冲区中.紧紧挨在一起,此时B的应用程序在读数据的时候,就难以区分从哪到哪是一个完整的应用层数据报
很容易读出半个包,一个半包的情况
不同的服务器会给出不同的解决方案,例如使用特定的分隔符来隔开
又或者约定长度等等