网上 关于 TCP三次握手 的文章有很多,但很多一些部分讲的含糊其辞,所以才重新造了这个轮子,一方面对那些含糊其辞的部分做了解释,另一方面也方便了以后的学习。
1、上图的名词解释
- SYN:同步序号。
它表示建立连接
。TCP规定SYN=1时不能携带数据,但要消耗一个序号, 因此随机选取一个序列号为seq=x 数据包(该数据包里就是一个标记seq,并没有任何有效的数据)。 - ACK :确认序号。
它表示响应
(都能响应了 那肯定上一步就连接成功了啊,所以说ACK=1代表确认连接成功啦)。
因此SYN和ACK同时为1,表示建立连接之后的响应
;而只是单个的SYN=1,表示的只是建立连接
。
- seq: (sequence number) 序列号。它是发送端数据包的初始序号。
seq=x 表示发送端数据包的初始序号为x
(seq = 0 就代表这是第0号帧)。 - ack:(acknowledge number) 确认号。它是对这次收到数据包的确认,以及对下次收到数据包的期待。
ack=x+1表示 我方 到 x为止的所有数据都已正确收到,且我方告知 对方:我期待你下次给我发送包的初始序号(seq)是x+1
。
为了方便记忆,可以这么理解:SYN/ACK是TCP协议层面的标记,而seq/ack是数据层面的标记。
2、TCP三次握手 过程
( 1 )首先Client向Server发送连接:SYN = 1, seq=x;
因为
要建立连接,所以SYN=1
;又因为
TCP规定SYN=1时不能携带数据,但要消耗一个序号,所以
Client随机选取一个初始序号seq=x
。(因为并没有响应动作,所以这里没ACK什么事,我们就认为ACK=0吧)- 发送后Client进入syn_sent状态,表示客户端等待服务器的回复。
(2)Server收到请求后 再向Client发送确认:SYN=1, ACK=1, seq=y, ack=x+1;
因为
Server建立连接后做出了响应,所以SYN=1, ACK=1
。因为
TCP规定SYN=1时不能携带数据,但要消耗一个序号,所以
Server随机选取一个初始序号seq=y
。又因为
Server到 x为止的所有数据都已正确收到了,且Server告诉Client:我期待你下次给我发送包的初始序号(seq)是x+1,所以ack=x+1
。- 发送后服务器进入syn_rcvd,表示服务器已经收到Client的连接请求,等待Client的确认。
(3)Client收到确认后还需再次发送确认,同时携带要发送给Server的数据:ACK=1, seq=x+1, ack= y+1;连接建立
因为
有 响应 动作,所以ACK=1
(因为要携带发送的数据,所以这儿没SYN什么事)。因为(2)
中Server 已经告诉了这次它想收到包的初始序列号是x+1,所以初始序号为seq=x+1
。又因为
Client到 y为止的所有数据都已正确收到了,准备接收序列号为y+1的包,所以ack=y+1
。- Server收到后,这个TCP连接就进入Established状态,就可以发起http请求了。
3、为什么不能改成两次握手?
有人会困惑为什么要进行三次握手呢(两次确认)?这主要是为了防止已失效的请求连接报文忽然又传送到了,从而产生错误。
假定A向B发送一个连接请求,由于一些原因,导致A发出的连接请求在一个网络节点逗留了比较多的时间。此时A会将此连接请求作为无效处理 又重新向B发起了一次新的连接请求,B正常收到此连接请求后建立了连接,数据传输完成后释放了连接。如果此时A发出的第一次请求又到达了B,B会以为A又发起了一次连接请求,如果是两次握手:此时连接就建立了,B会一直等待A发送数据,从而白白浪费B的资源
。 如果是三次握手:由于A没有发起连接请求,也就不会理会B的连接响应,B没有收到A的确认连接,就会关闭掉本次连接
。
以上便是全部,如有解释不对的地方望及时指出~
来源:CSDN
作者:我叫白天宇
链接:https://blog.csdn.net/b954960630/article/details/81861579