TCP三次握手与四次挥手

背景

作为一名后端开发人员,其实需要掌握的知识还真的需要很多的很多的。这也是我自己一直为什么觉得作为程序员是一种幸福,因为很多的知识与技术都掌握在了其他的人前面,可能享受到这个世界知识带来的红利。但技术也是孤独的,越是往深的地方走,越是觉得自己的无知。

这几个月对于知识的深入也是养成了一些习惯,对于源码与原理性的东西越发的感兴趣。也想着自己多输出一些东西出来。也算是记录自己的一个成长吧!

TCP的三次握手

三次握手主要是针对于Client与Server建立连接来描述的。

https://img-blog.csdn.net/20170911145000723

第一次握手:由客户端发起TCP连接的请求,此时客户端发送一条报文,其中包含SYN标志位,将SYN设置为1; 以及seq位。设seq = x ; 该报文段成为SYN报文段;

第二次握手:服务器收到这条报文后,返回给客户端一条报文,包含ack位、SYN、以及seq位。 其中ack = x+1; SYN = 1; seq = y。该报文段称为SYNACK报文段;

第三次握手:当客户端收到SYNACK报文段之后,客户端需要再给服务器发送另外一个报文段,进行确认。该报文段的SYN = 0, seq = x +1,ack = y+1;

总结一下,就是客户端先跟服务端做一个试探,看看服务端是不是可以被连接的,如果回复是可以的,那么客户端才真的发起请求过去。

TCP的四次挥手

四次挥手主要是针对于Client与Server关闭连接来描述的。

https://img-blog.csdnimg.cn/20191102213543484.png

TCP连接数据传输结束后,通信的双方client与server都可以选择释放当前TCP连接,此时client与server都处于ESTABLISHED(连接确立)状态,TCP连接释放从此状态开始,我们假设是client的应用进程主动发起TCP连接释放:

第一次挥手:client向server主动发送连接释放报文(FIN=1,seq=u),报文的首部控制位FIN=1,代表自己的数据已经发送完毕,并且要求释放TCP连接。序号seq=u,u的值为client前面已传送数据的最后一个字节序号加1,client发送完后进入FIN-WAIT-1(终止等待1)状态。

第二次挥手:server收到client的连接释放报文后即给出确认报文(ACK=1,ack=u+1,seq=v),序号seq=v,值为server前面已传送数据的最后一个字节序号加1,然后server进入CLOSE-WAIT(关闭等待)状态。这时候client到server这个方向连接就释放了,TCP连接处于 半关闭(half-close)状态,client不再发送数据,但是server仍然可以发送数据给client。client收到server确认后进入FIN-WAIT-2(终止等待2)状态,然后等待server发出连接释放报文。

第三次挥手:处于CLOSE-WAIT状态的server发送完所有数据后,主动释放连接,server发送的连接释放报文(FIN=1,ACK=1,seq=W,ack=u+1),因为半关闭状态,server可能又发送了一些数据,所以序号的值为W,同时保持确认号ack=U+1与上次一致,发送完毕后,server进入LAST-ACK(最后确认)状态,等待client确认。

第四次挥手:client收到server连接释放报文后,给出确认报文(ACK=1,ack=w+1,seq=u+1),此时连接还没释放掉,client要时间等待计时器设置的2MSL的时间,才最终进入CLOSED状态。时间MSL是最长报文寿命时长,RFC793建议为2分钟,但是现在网络中,这个时间设置更小。也就是说client要等待4分钟才能进入CLOSED状态,开始下一个连接。

疑问点

1、为什么client在TIME-WAIT状态必须等待2MSL的时间?
  • 为了保证client的最后发送的ACK报文能到达server。因为这个ACK报文可能丢失,导致处于LAST-ACK状态的server收不到对自己释放连接报文的确认。若是server超时重传了这个报文,client就能在2MSL时间内收到,并且重新一次确认,并重启2MSL计时器。
  • 防止出现“已失效的连接请求报文段”出现,2MSL时间,可以使本连接持续时间内的报文段都从网络中消失。建立下一个TCP连接时就不会出现上次旧连接请求报文段。
2、如果一方突然出故障了怎么办?

在TCP连接建立后,client与server传输过程中,假设client突然出故障了,server显然无法再收到client数据了,但是server不能白白等下去。这时TCP的保活计时器(keepalive timer)就登场了。server每收到一次client的数据,就重新设置一下计时器,时间通常是2小时,若2小时内没有再收到client数据,server就会发送一次探测报文段,以后每隔75分钟发送一次,若一连发送10次,client都没有任何响应,server会认为client故障了,直接关闭连接。

https://img-blog.csdnimg.cn/20191103114603194.png

该篇博文基本上属于一个科普性的文章,基本也是参考了@magic1024@qq39833075 的文章,尊重别人的原创。

参考地址

简栈文化服务订阅号