TCP为什么要三次握手?
什么是 TCP?
首先来说 TCP(Transmission Control Protocol,传输控制协议)是一个面向连接的、可靠的、基于字节流的传输层协议。从它的概念中我们可以看出 TCP 的三个特点:面向连接、可靠性和面向字节流。
面向连接:是指 TCP 是面向客户端和服务器端连接的通讯协议,使用它可以将客户端和服务器端进行连接。
可靠性:是指无论网络环境多差,TCP 都可以保证信息一定能够传递到接收端。
TCP 之所以可以保证可靠性主要得益于两个方面,一个是“状态性”,另一个是“可控制性”。所谓状态性是指 TCP 会记录信息的发送状态,例如,哪些数据收到了、哪些数据没收到等状态信息都会被记录;可控制性是指 TCP 会根据状态情况控制自己的行为,比如当 TCP 意识到丢包了就会控制重发此包,这样就实现了 TCP 的可靠性。
面向字节流:是指 TCP 是以字节流的方式进行数据传输的。
小贴士:TCP 之所以被广泛应用,首先是因为它是一个标准化的协议,TCP 的标准协议就是由 RFC 793 定义的,它已经有了 30 多年的历史,并且已经被多次更新。RFC(Request For Comments)是 IETF(Internet Engineering Task Force)的正式文档。IETF 是一家制定互联网标准的组织,它制定了 Internet(互联网)的整体协议体系,凡是经过 IETF 评审认可的标准都会被发布为带编号的 RFC 的文档。
TCP 定义的大致意思是,用于保证可靠性和流控制机制的信息,包括 Socket、***及窗口大小被称为连接。
其中,Socket 是由 IP 地址加端口号组成的,***是用来解决乱序问题的,而窗口大小则是用来做流量控制的。
接下来我们来看 TCP 三次握手的执行流程,如下图所示:
关键字说明:
-
SYN(Synchronize Sequence Numbers),同步序列编号;
-
ACK(Acknowledge Character),确认字符;
-
SEQ(Sequence Number),***。
TCP 的执行流程如下:
-
最开始时客户端和服务端都处于 CLOSED 状态,然后服务端先主动监听某个端口,此时服务器端就变成了 LISTEN(监听)状态;
-
然后客户端主动发起连接,发送 SYN(同步序列编号),此时客户端就变成了 SYN-SENT 状态;
-
服务端接收到信息之后返回 SYN 和 ACK 至客户端,此时服务器端就变成了 SYN-REVD 状态;
-
客户端接收到消息之后,再发送 ACK 至服务器端,此时客户端就变成了 ESTABLISHED(已确认)状态,服务端收到 ACK 之后,也变成了 ESTABLISHED 状态,此时连接工作就执行完了。
为什么 TCP 需要三次握手?
原因一:防止重复连接:三次握手的主要原因是为了防止旧的重复连接引起连接混乱问题
比如在网络状况比较复杂或者网络状况比较差的情况下,发送方可能会连续发送多次建立连接的请求。如果 TCP 握手的次数只有两次,那么接收方只能选择接受请求或者拒绝接受请求,但它并不清楚这次的请求是正常的请求,还是由于网络环境问题而导致的过期请求,如果是过期请求的话就会造成错误的连接。
所以如果 TCP 是三次握手的话,那么客户端在接收到服务器端 SEQ+1 的消息之后,就可以判断当前的连接是否为历史连接,如果判断为历史连接的话就会发送终止报文(RST)给服务器端终止连接;如果判断当前连接不是历史连接的话就会发送指令给服务器端来建立连接。
原因二:同步初始化序列化
通过上面的概念我们知道 TCP 的一个重要特征就是可靠性,而 TCP 为了保证在不稳定的网络环境中构建一个稳定的数据连接,它就需要一个“***”字段来保证自己的稳定性,而这个***的作用就是防止数据包重复发送,以及有效的解决数据包接收时顺序颠倒的问题。
那么在建立 TCP 连接时就需要同步初始化一个***来保证 TCP 的稳定性,因此它需要执行以下过程:
-
首先客户端发送一个携带了初始***的 SYN 报文给服务器端;
-
服务端接收到消息之后会回复一个 ACK 的应答报文,表示客户端的 SYN 报文已被服务端成功接收了;
-
而客户端收到消息之后也会发送一个 ACK 给服务端,服务器端拿到这个消息之后,我们就可以得到一个可靠的初始化***了。
而如果是两次握手的话,就无法进行***的确认工作了,因此也就无法得到一个可靠的***了,所以 TCP 连接至少需要三次握手。
以上两种原因就是 TCP 连接为什么需要三次握手的主要原因,当然 TCP 连接还可以四次握手,甚至是五次握手,也能实现 TCP 连接的稳定性,但三次握手是最节省资源的连接方式,因此 TCP 连接应该为三次握手。
知识扩展
UDP 介绍
UDP(User Data Protocol,用户数据报协议)是无连接的、简单的、面向数据报的传输层协议。也就是 UDP 在发送数据之前,无须建立客户端与服务端的连接,直接发送消息即可。
UDP 的协议头有 8 个字节(64 位),如下图所示:
UDP 的协议头
其中源端口和目标端口是指记录发送方和接收方端口;UDP 包长度是指 UDP 头部加上 UDP 数据的总长度;UDP 校验和用于效验 UDP 的内容是否可靠。
UDP 常见的使用场景有:语音、视频等多媒体通信、DNS(域名转化)、TFTP 等。
TCP VS UDP
TCP 和 UDP 的区别主要体现在以下 7 个方面:
-
可靠性,TCP 有“状态性”和“可控制性”可以保证消息不重复、按顺序、不丢失的发送和接收,而 UDP 则不能保证消息的可靠性;
-
连接,TCP 是面向连接的传输层协议,传输数据前先要建立连接,而 UDP 发送数据之前无需建立连接;
-
服务对象,TCP 服务的对象为一对一的双端应用,而 UDP 可以应用于一对一、一对多和多对多的通信场景;
-
效率,TCP 的传输效率较低,而 UDP 的传输效率较高;
-
流量控制,TCP 有滑动窗口可以用来控制流量,而 UDP 则不具备流量控制的能力;
-
报文,TCP 是面向字节流的传输层协议,而 UDP 是面向报文的传输层协议;
-
应用场景,TCP 的应用场景是对消息准确性和顺序要求较高的场景,而 UDP 则是应用于对通信效率较高、准确性要求相对较低的场景。
TCP 和 UDP 的使用场景如下图所示: