TCP的三握四挥

Lee
Lee
发布于 2024-02-18 / 14 阅读
0
0

TCP的三握四挥

前言:在浏览器中输⼊URL并按下回⻋之后会发⽣什么?

1. 第⼀步:输⼊URL并解析 这⾥可以引申到URL的组成部分,这⾥不做过多的展开。 输⼊ URL 后,浏览器会解析出协议、主机、端⼝、路径等信息,并构造⼀个HTTP请求(浏览器会根据请求头判断 是否有 HTTP缓存 ,并根据是否有缓存决定是从服务器获取资源还是使⽤缓存资源,具体内容会在HTTP缓存章节讲 解)

2. 第⼆步:DNS域名解析, 将域名解析成对应的IP地址 在发送HTTP请求之前,浏览器需要知道想要访问⽹⻚(url)对应的IP地址,这就需要使⽤到 DNS域名解析 (DNS域名 解析的具体内容也会在后⾯章节中讲解)。

3. 第三步:建⽴起TCP连接之三次握⼿ 这⾥是重中之重,可以扩展很多问题,⽐如为什么是三次,不是两次、四次?如果第⼀次握⼿丢失了会发⽣ 什么?三次握⼿过程中可以携带数据吗? 客户端和服务器之间进⾏HTTP请求和HTTP响应的过程中,需要建⽴起TCP连接,TCP连接需要进⾏三次握⼿(具 体内容在后⾯章节中讲解)。

4. 第四步:浏览器发送HTTP/HTTPS请求到web服务器 这⼀步也可以扩展很多问题,⽐如HTTP/HTTPS的区别?请求的⽅式?请求的状态码,凡是与HTTP请求的问 题都可以问。

5. 第五步:服务器处理HTTP请求并返回HTTP报⽂ HTTP响应报⽂和状态码也是常考的内容。 服务器会接受请求并将其传递给请求处理程序并发送HTTP响应,⼀般响应报⽂包含:请求的⽹⻚以及状态码,压 缩类型,如何缓存的⻚⾯,设置的cookie;

6. 第六步:浏览器渲染⻚⾯ 浏览器渲染⻚⾯的流程对于前端同学来说也是必会的、还会牵扯到回流和重绘的问题。

7. 第七步:断开连接之TCP四次挥⼿ 这⾥也是特别重要的知识点,四次挥⼿的过程,为什么是四次? 客户端和服务器之间断开连接需要进⾏四次挥⼿

TCP三次握手

握手过程

问题:为什么需要三次握⼿?

  1. 三次握⼿才可以阻⽌重复历史连接的初始化(主因)

1. 当因为⽹络阻塞原因,客户端向服务器发送了两次SYN报⽂

2. 旧的SYN报⽂先到达服务端,服务端回⼀个ACK+SYN报⽂

3. 客户端收到后可以根据⾃身的上下⽂,判断这是⼀个历史连接(序列号过期或超时),那么客户端就会发送 RST 报⽂给服务端,表示中⽌这⼀次连接。

4. 服务器收到RST报⽂,会释放连接

5. 新的SYN报⽂抵达之后,客户端和服务器之间进⾏正常的三次握⼿ 如果只是两次握⼿,服务端在收到SYN报⽂之后,就进⼊到 ESTABLISHED 状态, 服务器端并不知道这次是历史连 接,直接与客户端建⽴连接并向客户端发送数据(资源浪费),但是客户端会判定这次连接是历史连接,从⽽发送 RST报⽂来断开连接。

所以要想让服务器发送数据前,阻⽌掉历史连接,就需要三次握⼿。

2.三次握⼿才可以同步双⽅的初始序列号

1. 客户端发送第⼀个报⽂,携带客户端初始序列号的SYN报⽂。

2. 服务器发送第⼆个报⽂,携带服务器初始序列号的ACK + SYN的应答报⽂,表示收到客户端的SYN报⽂。

3. 客户端发送第三个报⽂,携带服务器的ACK应答报⽂。

这样⼀来⼀回,才能确保双⽅的初始序列号能被可靠的同步。 两次握⼿只保证了⼀⽅的初始序列号能被对⽅成功接收,没办法保证双⽅的初始序列号都能被确认接收。四次握⼿ 也能保证双⽅的初始化序号同步,但是可以省略成三次。

3.三次握⼿才可以避免资源浪费

1. 只有两次握⼿时,如果客户端的SYN请求连接在⽹络中阻塞,客户端没有收到服务端的ACK报⽂,会重新发送 SYN。

2. 由于没有第三次握⼿,服务器不清楚客户端是否收到了⾃⼰发送的建⽴连接的 ACK 确认信号,所以每收到⼀ 个 SYN 就只能先主动建⽴⼀个连接, 建⽴多个冗余的⽆效链接,造成不必要的资源浪费

问题:什么是半连接队列 ?

半连接队列(SYN队列)

⽤于存放已经发送了 SYN(同步)包,但还未完成三次握⼿的连接:服务器第⼀次收到客 户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双⽅还没有完全建⽴其连接,服务器会把此种状态下请求连接 放在⼀个队列⾥,我们把这种队列称之为半连接队列。 全连接队列(Accept队列)⽤于存放已经完成三次握⼿,处于完全建⽴连接状态的连接。

问题:什么是SYN攻击 ?

在 SYN 攻击中,攻击者发送⼤量伪造的 SYN 请求到⽬标服务器,但不完成后续的握⼿过程,从⽽让服务器⼀直等 待确认,消耗服务器的资源(如半连接队列和系统资源),当半连接队列满了之后,后续再收到SYN报⽂就会丢 弃,导致⽆法与客户端之间建⽴连接。

TCP四次挥⼿

挥手过程

问题:为什么挥⼿需要四次?

关闭连接时,客户端发送FIN报⽂,表示其不再发送数据,但还可以接收数据。 服务端收到FIN报⽂,可以直接发送SYN+ACK报⽂。其中ACK报⽂是⽤来应答的,SYN报⽂是⽤来同步的。但是关 闭连接时,服务端可能还要数据需要处理和发送,所以先回⼀个ACK应答报⽂,等到其不再发送数据时,才发送 FIN报⽂给客户端表示同意关闭连接。 从上⾯过程可知:服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN⼀般都会分开发送,从⽽ ⽐三次握⼿导致多了⼀次。

问题:为什么需要 TIME_WAIT 状态 ?

主动发起关闭连接的⼀⽅,才会有 TIME-WAIT 状态。 需要 TIME-WAIT 状态,主要是两个原因:

1. 防⽌历史连接中的数据,被后⾯相同四元组的连接错误的接收; 如果⽹络出现拥塞或延迟,数据包可能会在⽹络中滞留⼀段时间,甚⾄超过了原始连接关闭的时间。如果没有 TIME_WAIT 状态,客户端直接进⼊到CLOSE状态,这些滞留的数据包可能会被传递给新连接,导致新连接的数据 被旧连接的数据⼲扰。 经过 2MSL 这个时间,⾜以让两个⽅向上的数据包都被丢弃,使得原来连接的数据包在⽹络中都⾃然消失,再出现 的数据包⼀定都是新建⽴连接所产⽣的。

2. 保证「被动关闭连接」的⼀⽅能被正确的关闭,即保证最后的 ACK 能让被动关闭⽅接收,从⽽帮助其正常关 闭 如果最后的⼀次ACK报⽂丢失(第四次挥⼿),客户端没有 TIME_WAIT 状态,直接进⼊ClOSE,服务端⼀直在等待 ACK状态,⼀直没有等到,就会重发FIN报⽂,⽽客户端已经进⼊到关闭状态,在收到服务端重传的 FIN 报⽂后, 就会回 RST 报⽂,服务端收到这个 RST 并将其解释为⼀个错误, 为了防⽌这种情况出现,客户端必须等待⾜够⻓的时 间,确保服务端能够收到 ACK,如果服务端没有收到 ACK,那么就会触发 TCP 重传机制,服务端会重新发送⼀个 FIN,这样⼀去⼀来刚好两个 MSL 的时间。

问题:为什么 TIME_WAIT 等待的时间是 2MSL ?

1. MSL是 Maximum Segment Lifetime ,报⽂最⼤⽣存时间,它是任何报⽂在⽹络上存在的最⻓时间,超过这 个时间报⽂将被丢弃。

2. 等待MSL两倍:⽹络中可能存在发送⽅的数据包,当这些发送⽅的数据包被接收⽅处理后⼜会向对⽅发送响 应,所以⼀来⼀回需要等待 2 倍的时间。

3. 1 个 MSL 确保四次挥⼿中主动关闭⽅最后的 ACK 报⽂最终能达到对端;1 个 MSL 确保对端没有收到 ACK 重 传的 FIN 报⽂可以到达。

4. 2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端⼜接收到了服务端重发的 FIN 报⽂,那么 2MSL 时间将重新计时。

问题:TIME_WAIT 过多有什么危害?

过多的TIME-WAIT 状态主要的危害有两种:

1. 内存资源占⽤;

2. 对端⼝资源的占⽤,⼀个 TCP 连接⾄少消耗⼀个本地端⼝; 如果发起连接⼀⽅的 TIME_WAIT 状态过多,占满了所有端⼝资源,则会导致⽆法创建新连接。


评论