目录
一、TCP
1、特性
2、确认应答
(1)、定义
(2)、原理
(3)、接收缓冲区
3、超时重传
(1)、丢包
(2)、定义
(3)、分类
二、连接管理
1、特殊比特位
2、TCP建立连接——三次握手
(1)、定义
3、TCP断开连接——四次挥手
(1)、定义
三、效率机制和安全机制
1、滑动窗口——效率机制
(1)、定义
(2)、原理
(3)、批量发送过程中出现丢包
2、流量控制——安全机制
(1)、定义
(2)、原理
3、拥塞机制——安全机制
(1)、定义
(2)、原理
4、延迟应答——效率机制
(1)、定义
(2)、包的延迟应答限制
5、 捎带应答——效率机制
(1)、定义
一、TCP
1、特性
TCP协议是有连接、可靠传输、面向字节流和全双工的传输层通信协议
TCP可靠性的基石:
- 传输顺利时,使用确认应答保证可靠性。
- 出现丢包时,使用超时重传作为补充。
2、确认应答
(1)、定义
发送方在发送完数据之后,为了确认接收方是否收到数据,接收方会返回一个应答报文,表示自己已经收到数据。
注:确认应答是实现可靠性的核心机制。
例:
A向B发送一个申请,B回复一个应答报文 。
回复可能会因为一些原因导致顺序发送改变。为了解决这个问题,就需要针对消息进行编号,给发送的消息分配一个序号,同时应答报文,给出确认序号。
(2)、原理
确认序号的规则,不是说发送方的序号是什么,确认序号就是什么,而是取得发送方送过来的所有数据的最后一个字节的下一个字节的序号 。
TCP将每个字节的数据都进行了编号,即为序列号
发送方的确认序号是一个无意义的数据,接收方的序号和发送方的序号无关
确认序号1001的含义:
- 小于1001的数据表示已经收到
- 接下来要向发送方索要从1001开始的数据
接收方可以通过ack的确认序号,告诉发送方哪些数据已经收到了
(3)、接收缓冲区
对于TCP来说,自身也承担整个队列的任务,TCP会有一个接收缓冲区(一块内核中的内存空间),每个socket都有一份自己的缓冲区。TCP可以按照序号针对收到的消息进行整队。
应用程序读数据时,读到的一定是有序的和发送顺序一样。
3、超时重传
(1)、丢包
丢包是网络上非常典型的情况,由于网络环境复杂,数据传输过程中难免遇到意外,每一次数据传输都有可能丢失。
每个设备都承担很多的转发任务,中间任何一个节点出了问题都可能导致丢包。每个设备转发能力都是有上限的,某一时刻某个设备上面的流量达到峰值就可能引起部分数据被丢包
(2)、定义
每次数据传输如果成功,都应收到ack。如果包丢了接收方就收不到,就不会返回ack。
发送方拿不到应答报文,等待一段时间后还是没有收到应答报文,发送方就视刚才的数据丢包了,这就会触发超时重传机制,重新发送一次数据。
(3)、分类
- 数据直接丢了,接收方没有收到,所以不会发送ack
- 接收方收到数据,但返回的ack丢了
发送方是区分不了这两种情况,只能重传。
注:
TCP针对多个包丢失,处理思路是继续超时重传。但是连续触发超时重传会让等待时间增加,重传的频率降低。超过一定次数后还没收到ack后就会断开连接,TCP会尝试重置连接,如果重置连接也失效,TCP就会关闭连接,放弃传输数据。(能重传就重传,传不了就关闭,尽最大可能完成传输)
二、连接管理
1、特殊比特位
这6个特殊的比特位默认是0,如果为1表示特定含义:
- 第二位是ack,如果这一位为1,表示当前TCP数据报是一个应答报文
- 第五位是syn,如果这一位为1,表示当前TCP数据报是一个同步报文
- 第六位是fin,如果这一位为1,表示当前TCP数据报是一个结束报文
2、TCP建立连接——三次握手
(1)、定义
握手指的是通信双方,各自进行一次网络交互。相当于客户端和服务器之间,通过三次交互,建立了连接关系,双方各自记录对方的消息。
三次握手这个过程本质上是投石问路,验证了客户端和服务器各自的发送能力和接收能力是否正常。
- 首先客户端向服务器发送syn(连接请求)
- 服务器接收到syn后,向客户端返回ack,同时服务器向客户端发送syn
- 客户端收到syn后向服务器返回ack
注:上述过程由内核自动完成,应用程序干预不了。等到连接完成,服务器accept把建立好的连接从内核拿到应用程序中。
例:
- B收到了A的问话,此时B知道:A麦克风正常,自己的耳机正常
- A收到了B的回答和问话,A知道:自己的耳机和麦克风正常;B的耳机和麦克风正常。
- B收到A的回答,B知道:自己的麦克风正常;A的耳机正常。
确认了客户端和服务器各自的发送能力和接收能力都正常,这就是后续可靠传输的基础
注:上述流程中间的syn和ack拆开分别发送同样能够达成目的。但是没有必要,分层两次发送效率不如合并成一次(封装和分用)。
3、TCP断开连接——四次挥手
(1)、定义
通信双方,各自给对方发送一个fin(结束报文),再各自给对方返回ack。
- 客户端向服务器发送一个fin(结束报文)
- 服务器接收到fin后,向客户端返回一个ack
- 服务器同时向客户端发送一个fin
- 客户端接收到fin后向服务器返回一个ac
注:ack和fin有一定概率合并成一个的,但是通常情况下不能合并。
- 三次握手:ack和syn是同一个时机触发的(都是内核来完成的)
- 四次挥手:ack和fin则是不同实际触发的,ack是内核完成的,会在收到fin时的第一时间返回;fin则是应用程序代码控制的,在调用到socket的close方法时才会触发fin
三、效率机制和安全机制
1、滑动窗口——效率机制
(1)、定义
对每一个发送的数据段,都要给一个ack确认应答。收到ack后再发送下一个数据段,这样做有一个比较大的缺点就是性能较差,尤其是数据往返的时间较长的时候。
TCP要保证的不仅仅是可靠性还有效率,提升可靠性往往意味着损失效率。因此为了弥补效率我们引入了滑动窗口这一机制:
相比发送一条数据, 收到ACK后发送下一条, 滑动窗口可以一次性发送 N 条数据报,收到 M 条 ACK 的应答后, 窗口向右移动M个位置,并继续发送窗口中没有发送的数据。这样就可以做到将多个 ACK 的等待时间重叠在一起,使用一份时间等待多个ack,总的等待时间缩短了,整体的效率就提升了。
批量发送数据:一次发送多条数据,一次等多个ack,称为滑动窗口
注意:UDP更快,TCP再怎么提高效率都不可能比UDP快,TCP的效率机制本质上是让性能折损少一点。
(2)、原理
批量发送不是无限的,是发送到一定程度就等待ack。不等待直接发送的数据量是有上限的,而且回来一个ack就立即发下一条,相当于总的要批量等待的数据是一致的,把批量等待数据的数量就称为“窗口大小” 。
批量发了四条数据就等待四个ack,红色的区域就相当于等待窗口
当收到2001这个ack意味着1001-2000这个数据得到了确认,此时就会立即发下一个5001-6000这个数据。此时看到的效果就好像窗口还是这么大,但是往后挪了一个格子。如果收到的ack非常快,此时这个窗口就在快速的往后滑动。
(3)、批量发送过程中出现丢包
【1】、ack丢了
例:当收到2001这个ack时,此时发送方就知道了,2001之前的数据收到了。1-1000这个数据也收到了,1001这个ack丢了无所谓。如果是最后一个丢了,就照常超时重传。滑动窗口是锦上添花,不是说前面的超时重传就没了。如果批量发送,滑动窗口说了算。
注:这种情况没事,即使丢了这么多ack,对于可靠性没有任何影响。确认序号的含义,表示该序号之前的数据都已经收到了。后一个ack能够涵盖前一个ack的意思。
【2】、数据丢了
上述重传过程没有任何冗余的的操作,丢了数据才会重传,不丢的数据不必重传。整体数据是比较快的,这个重传过程也称为快速重返。
当1001这个数据重传过来之后,此时缺失的拼图就补全了,接下来就要从7001开始索要
如果是4001也没有,收到1001-2000之后,接下来返回ack就是索要4001,也是同理,反复索要多次发送发就会重传4001。
注:滑动窗口,快速重传,是在批量传输大量数据时,会采取的操作。如果你就只传输一条两条,少量的,低频的操作。就不会按滑动窗口这么做,仍然是前面朴素的确认应答和超时重传。
2、流量控制——安全机制
(1)、定义
滑动窗口,批量发送。窗口越大,批量发送的数据越多,整体的速度就越快。但是窗口不能是无限大,如果发送太快瞬间把接受方接收缓冲区给打满了,接下来继续发送,此时数据就会丢包。
TCP支持根据接收端的处理能力来决定发送端的发送速度,这个机制就叫做流量控制。
因此我们可以通过流量控制来解决问题,本质上就是让接收方来限制一下发送方的速度。
(2)、原理
在网络通信中, 发送方的数据会通过网卡发送到接收缓冲区中, 接收缓冲区在操作系统内核中,可以视为一个阻塞队列,而接收方的应用程序则是会不断从接收缓冲区中处理数据。
- 接收端将自己可以接收的缓冲区大小放入TCP首部中的窗口大小字段,通过ack端通知发送端。窗口大小字段越大,说明网络的吞吐量越高。
- 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端。
- 发送端接受到这个窗口之后,就会减慢发送速度。
- 如果接收端缓冲区满了,就会将窗口置为0。发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。
接收方计算窗口大小:简答粗暴,直接拿接收缓冲区,剩余空间作为窗口大小。
如果接收缓冲区满了,这时窗口为0,也就是发送方暂时发不了数据了,只能等待缓冲区位置空出来,这期间会向接收方发送探测报文,这个数据报的作用就是让接收方返回带有滑动窗口大小数据的 ACK 数据报, 以重新调整窗口大小。
3、拥塞机制——安全机制
(1)、定义
虽然TCP有滑动窗口能够高效可靠的发送大量的数据,但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,冒然发送大量数据会出现问题。
TCP引入慢启动机制,先发少量的数据,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。
(2)、原理
- 引入一个概念为拥塞窗口
- 发送开始时,定义拥塞窗口大小为1
- 每次收到一个ack应答,拥塞窗口加1
- 每次发送数据包时,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口
例:
- 当TCP开始启动的时候,慢启动阈值等于窗口最大值
- 在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1
4、延迟应答——效率机制
(1)、定义
假设接收端缓冲区为1M,一次收到了500K的数据,如果立刻应答返回的窗口就是500K。但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了。在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来。如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M。
窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率
(2)、包的延迟应答限制
- 数量限制:每隔N个包就应答一次;
- 时间限制:超过最大延迟时间就应答一次;
5、 捎带应答——效率机制
(1)、定义
在延迟应答的基础上,客户端服务器在应用层也是 "一发一收" 的。这意味着客户端给服务器说了 "How are you",服务器也会给客户端回一个 "Fine, thank you"。那么此时ack就可以搭顺风车,和服务器回应的 "Fine,thank you" 一起传输给客户端。