TCP的三次握手&四次挥手

1. 三次握手

三次握手过程:

第一步:client 发送 syn 到server 发起握手;
第二步:server 收到 syn后回复syn+ack给client;
第三步:client 收到syn+ack后,回复server一个ack表示收到了server的syn+ack(此时client的端口的连接已经是established)。
 

从应用层角度深度理解TCP三次握手和队列:

源于博客:https://blog.csdn.net/alitech2017/article/details/80922902

如上图所示,这里有两个队列:syns queue(半连接队列);accept queue(全连接队列)。

三次握手中,在第一步server收到client的syn后,把这个连接信息放到半连接队列中,同时回复syn+ack给client(第二步);


第三步的时候server收到client的ack,如果这时全连接队列没满,那么从半连接队列拿出这个连接的信息放入到全连接队列中,否则按tcp_abort_on_overflow指示的执行。

这时如果全连接队列满了并且tcp_abort_on_overflow是0的话,server过一段时间再次发送syn+ack给client(也就是重新走握手的第二步),如果client超时等待比较短,client就很容易异常了。

在我们的os中retry 第二步的默认次数是2(centos默认是5次):
 

关于三次握手的几个问题

问题1:为什么TCP要三次握手?

1.TCP是面向连接服务,是全双工的。

2.TCP三次握手目的是同步连接双方的序列号和确认序列号,确认双方有接发数据的能力。

防止半路丢包导致连接失败(超时重发),server会接收很多多余信息。

假设丢包情况发生,那么服务器收不到ACK,连接不会建立,还会向客户端不停发送ACK,虽然客户端会收到很多SYN但这样避免了服务器收到冗余数据,效率下降。
 

问题2:为什么不可以两次或者四次?

1.因为server在LISTEN状态下会把ACK和SYN一起发送给Client。

2.如果两次握手,那么就是client发送SYN,server回应ACK就可以建立连接了。当server发送的ACK丢失情况,Client会认为没有连接,而server认为ACK已经发出去,Client就会不断给server发送SYN请求。server本就是一对多的,这会导致服务器效率降低。

3.两次握手下,假如SYN丢包了,客户端会定时再次发送。 假如SYN包一直延迟到连接都已经结束了断开了,服务器才收到,服务器会以为这是新的连接申请,给客户端发ACK响应,但客户端并没有发送再SYN,不予理会,服务器会以为连接成功。这样会浪费服务器可用资源。但假设服务器发送ACK之后还要听一听客户端的“想法”,那就是三次握手了。 

两次最主要的是

丢包会让服务器接收大量多余数据,增加服务器的处理工作;

网络延迟会让服务器发送无用数据;

最后没有确认机制,不能确定双方连接成功;

而三次已经解决了这个问题,所以当然不需要四次握手了。

 

2. 四次挥手


 

第一次挥手:

Client (可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向 Server发送一个FIN报文段;此时,Client 进入FIN_WAIT_1状态;这表示 Client 没有数据要发送给 Server了;

客户端发送第一次挥手后,就不能在向 服务端发送数据了。

第二次挥手:

Server 收到了 Client 发送的FIN报文段,向 Client 回一个ACK报文段,Acknowledgment Number 为 Sequence Number 加 1;Client 进入 FIN_WAIT_2 状态;Server 告诉 Client ,我“同意”你的关闭请求;

Server 第一次响应后,还可以继续向 Client 发送数据,这里只是告诉 Client ,我收到你发送的关闭请求。

第三次挥手

Server 向 Client 发送 FIN 报文段,请求关闭连接,同时 Server 进入 CLOSE_WAIT 状态;

当 Server 的数据响应完成后,再告诉 Client,我这边也可以关闭请求了, 这时
Server 就不能再向 Client 发送数据了

第四次挥手

Client 收到 Server 发送的 FIN 报文段,向 Server 发送 ACK 报文段,然后 Client 进入
TIME_WAIT 状态;Server 收到 Client 的 ACK 报文段以后,就关闭连接;此时,Client
等待2MSL后依然没有收到回复,则证明 Server 端已正常关闭,那好,Client 也可以关闭连接了。

msl:报文最大生存时间。根据系统不一样,一般是1min、4min左右

 

同样,几个问题

问题1:为什么TCP要四次挥手断开连接?

TCP是全双工的,所以两个方向的接收都得关闭,防止半路丢包或是传输失败。

一方是主动关闭,一方是被动关闭。

在断开连接时,发送一次FIN仅仅表示这一端不再发送数据收到ACK后变为TIME_WAIT状态,依旧可以接收在已经路上的数据,当收到server的FIN时发送ACK,server关闭,但是client还要等2个msl时间才能关闭。

问题2:为什么client的TIME_WAIT状态要等待2个msl才能关闭?

1.msl时TCP报文最大生存时间,因此2msl就可以保证两个传输方向上的未被接受或迟到的报文都已经消失。

2.主动断开的一方必须等一段时间才可CLOSED,理论上也保证了最后一个响应报文可靠到达。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值