TCP为什么三次握手?

参考:公众号 小林coding

常见回答:三次握手保证双方都具有接受和发送数据的能力。

主要原因:

1. 防止重复历史连接的初始化

2.同步双方初始序列号

3.避免资源的浪费

1. TCP为什么三次握手?

1.1  防止重复历史连接的初始化

TCP为什么三次握手?_第1张图片

序列号seq标记已发送数据的位置,确认号ack表示数据已接受,期望下一次数据序列号seq = ack

当因为网络拥塞导致超时重传建立连接的请求:设两次请求seq分别为:100, 200,在第二次请求发送后,客户端记录seq = 200, 即使网络恢复旧请求成功得到响应,此时ack = 101, 在客户端处校验不通过,发送RST终止这次连接。

如果采用两次握手:(中间绿色的服务端发送数据就被浪费,并且需要进行连接的销毁

TCP为什么三次握手?_第2张图片

 1.2 同步双方初始序列号

使用序列号可以保证数据的发送是有序的,同时记录已发送数据的位置,便于对比请求响应ack确定下一次发送数据的位置。

在三次握手的情况下,双方都对请求作出响应,表示数据接受,初始化发送数据的序列号;保证双方都进入数据可发送和接受的状态。

其中的四次握手,说的服务端响应阶段需要发送标志位:SYN, ACK,SYN用于初始化序列号,ACK表示确定数据接受成功;而最优的三次握手中,将这两个阶段放到一起,减少一次请求

3.其他问题

3.1 为什么客户端和服务端的初始化序列号不同?

可以注意到,在三次握手的建立过程中,很多情况下客户端的seq = x, 而服务端的序列号 seq = y

这样做的原因为了防止历史报文被下一个相同的四元组(tcp连接)接收

服务端和接收端中分别维护窗口大小,用于接收数据;如果使用不同的seq, 可以保证及时连接重置,旧的历史数据也很大程度不会落入接收窗口中,不会使数据污染。

假设每次初始化序列号都是0:

TCP为什么三次握手?_第3张图片

 

3.2 为什么要在传输层分片?

MTU:网络中最大数据包长度, 包括:IP头 + TCP头 + 数据报,以太网一般1500

MSS:最大数据报长度

当数据报超过MSS的时候进行数据分片。

如果在IP中进行分片,网络层中不包含重传机制,一旦某一个分片丢失,会导致这次请求的所有数据都要重传。

3.3 SYN攻击

        在TCP 连接建立是需要三次握手,假设攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的半连接队列,使得服务器不能为正常用户服务。

4、四次挥手

        进入连接断开阶段:

        第一次:客户端数据发送结束,发送FIN, 服务端接受后进入close_wait状态

        第二次:服务端响应客户端断开连接的请求

        第三次:服务端接收数据结束,发送FIN, 客户端接收后进入time_wait状态

        第四次: 客户端响应服务端请求,发送ack, 在time_wait阶段下等待2MSL时间;如果这个时间间隔内没有收到服务端的请求,进入close状态

主动关闭连接的,才有time_wait状态

相比于三次握手,这里的FIN 和 ACK需要分开,表示服务端仍可以接受数据;因此需要四次挥手

4.1 为什么需要2MSL

什么是MSL: 是报文段在网络中传输的最长时间;超过这个时间,就会被丢弃

2MSL:客户端发送确认报文ACK + 等待服务端请求(如果ACK丢失,重新发送FIN)两次请求的最长存活时间;当超过这个时间,表示报文发送成功。

4.2 为什么要有TIME_WAIT状态

1. 防止历史数据被后面相同的四元组(TCP连接)接收。假设第一次TCP连接中seq = 100, 整个过程中发送一次seq = 101的报文但是因为网络产生延迟,在TCP关闭前也没有成功接收。再重新建立一个TCP连接使用seq = 100, 此时上一次连接中的报文到达,并且接收窗口 [100, x]可以接受这次的数据;导致了新的连接接受了上一次的旧数据。

TCP为什么三次握手?_第4张图片

 

2. 保证接收数据方能够正常断开;如果没有2MSL, 当客户端发送ACK后直接进入关闭状态,如果ACK丢包,导致服务端重新发送FIN, 此时没有接收方,服务端一直没有断开连接


后续LInux中的看不懂。。。慢慢看吧,哎

你可能感兴趣的:(网络,网络)