=======
我们都知道 TCP 是具有可靠性的通信协议,它主要通过以下方式确保可靠性,这里先了解一下可靠性的原理,其中细节部分后文会讲:
-
合理的数据大小:TCP 发送的数据并不是固定的大小,而是会根据实际情况调整报文段的大小。
-
检验和:发送端按照特定算法计算出 TCP 报文段的检验和并存储在 TCP 首部中的对应字段上,接收端在接收时会以同样的方式计算校验和,如果不一致,说明报文段出现错误,会将其丢弃。
-
序号与确认序号:对乱序的数据进行排序后发给应用层,并丢弃重复的数据。
-
超时重传机制:当 TCP 发出一个报文段后,它会启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段,后面会细讲这个机制。
-
连接管理:也就是三次握手和四次挥手,连接的可靠性是整体可靠性的前提,本文第二部分将会详细介绍连接管理的内容。
-
流量控制:TCP 双方都有固定大小的缓冲区,流量控制的原理是利用滑动窗口控制数据发送速度,避免缓冲区溢出导致数据丢失。
-
拥塞控制:TCP 利用慢启动和拥塞避免等算法实现了拥塞控制。
上面为大家介绍了 TCP 最重要的三个特点,在本文第一部分的最后,再来看看 TCP 和 UDP 的对比吧。
1.4 TCP 和 UDP 的区别
=================
UDP |
TCP |
|
是否连接 |
无连接 |
面向连接 |
是否可靠 |
不可靠,没有确认机制、流量控制和拥塞控制 |
可靠,有确认机制、流量控制和拥塞控制 |
连接对象个数 |
支持一对一,一对多,多对一和多对多交互通信 |
只支持一对一通信 |
传输方式 |
面向报文 |
面向字节流 |
首部开销 |
首部开销小,固定8字节 |
首部开销较大,最小20字节,最大60字节 |
适用场景 |
适用于实时应用(IP电话、视频会议、直播等) |
适用于要求可靠传输的应用,如文件传输等 |
二、TCP 的连接控制
===========
2.1 建立连接
========
2.1.1 三次握手
==========
这个问题简直太经典了,如果你在面试中只被问到了一个关于 TCP 的问题,那大概率就是关于三次握手的问题。TCP 的重要特性之一就是面向连接,连接双方在发送数据之前必须经历握手的阶段,那具体的过程是怎样的呢?先来看图,大家最好可以动手简单画画这个图,当然还有后文四次挥手的图,帮助加深记忆。
三次握手过程
如图所示,双方之间的三个蓝色箭头就表示了三次握手过程中所发生的数据交换:
-
第一次握手:客户端向服务器发送报文段1,其中的 SYN 标志位 (前文已经介绍过各种标志位的作用)的值为 1,表示这是一个用于请求发起连接的报文段,其中的序号字段 (Sequence Number,图中简写为seq)被设置为初始序号x (Initial Sequence Number,ISN),TCP 连接双方均可随机选择初始序号。发送完报文段1之后,客户端进入 SYN-SENT 状态,等待服务器的确认。
-
第二次握手:服务器在收到客户端的连接请求后,向客户端发送报文段2作为应答,其中 ACK 标志位设置为 1,表示对客户端做出应答,其确认序号字段 (Acknowledgment Number,图中简写为小写 ack) 生效,该字段值为 x + 1,也就是从客户端收到的报文段的序号加一,代表服务器期望下次收到客户端的数据的序号。此外,报文段2的 SYN 标志位也设置为1,代表这同时也是一个用于发起连接的报文段,序号 seq 设置为服务器初始序号y。发送完报文段2后,服务器进入 SYN-RECEIVED 状态。
-
第三次握手:客户端在收到报文段2后,向服务器发送报文段3,其 ACK 标志位为1,代表对服务器做出应答,确认序号字段 ack 为 y + 1,序号字段 seq 为 x + 1。此报文段发送完毕后,双方都进入 ESTABLISHED 状态,表示连接已建立。
常见面试题 1:TCP 建立连接为什么要三次握手而不是两次?
答:网上大多数资料对这个问题的回答只有简单的一句:防止已过期的连接请求报文突然又传送到服务器,因而产生错误,这既不够全面也不够具体。下面给出比较详细而全面的回答:
-
防止已过期的连接请求报文突然又传送到服务器,因而产生错误在双方两次握手即可建立连接的情况下,假设客户端发送 A 报文段请求建立连接,由于网络原因造成 A 暂时无法到达服务器,服务器接收不到请求报文段就不会返回确认报文段,客户端在长时间得不到应答的情况下重新发送请求报文段 B,这次 B 顺利到达服务器,服务器随即返