标签:cli sock 之间 端口 ack 复位 位置 image 四次挥手
TCP/IP 协议TCP/IP协议的传输打包图解,反之则是解包
三次握手机制,是建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小信息,在socket编程中,客户端执行connect()时。将触发三次握手。
这边做一下解释:
1、第一次握手时,客户端发送一个TCP/IP的SYN标志位置1的包指明客户端打算连接的服务器的端口,以及初始化序号X,保存在包头的序列号Seq字段里。
2、第二次握手:
服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号ACK设置位客户的ISN加1,即图中的X+1。
3、第三次握手:
客户端再次发送确认包(ACK) SYN标志位为0 ACK标志位为1,并且把服务器发来的ACK的序号字段+1,放在确定字段中发送给对方,并且在数据段放写INS的+1。
TCP四次挥手
TCP的连接的拆除需要发送四个包,因此称为四次挥手。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
图解:
主动放发出信号即触发了挥手机制。
解释:
1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2??MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
这边常出现的面试题:
一、为什么连接的时候时三次握手,关闭的时候却是四次挥手?
解答:因为Server端受到的Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文使用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端受到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,通知Client端FIN报文Server端已经接收到了。但是Server端也并不能立即关闭连接,需要等待Server端的所有报文都发送完成后,Server才能发送FIN报文,因此SYN与ACK在Server端不能一并发送,所以需要四次挥手。
二、为什么TIME_WAIT(等待状态)需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
解答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,这样能真正的符合现实,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server端如果没有受到ACK,将不断重复的发送FIN片段。所以Client不能立关闭,它必须确认Server接收到了ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。而这里的2MSL是两倍的MSL(一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间)。如果知道2MSL,Client都没有再次收到FIN,那么Client会推断ACK已经成功接收,则结束TCP连接。
三、为什么不能用两次握手进行TCP/IP连接?
解答:3次握手完成两个重要的工作,既要双方做好发送数据的准备工作(双方都知道批次已经准备好了),同时也要允许双发就初始化序列号进行协商,这个序列号已经在握手的工作中被发送和确认。
如果把三次握手变成两次握手会怎么样呢?可能会导致死锁的发生。
图示:
解释:当两次握手,在假设A和B计算机之间开始了通讯,在A给B发送了一个请求连接分组,B也接收了并发送了确认应答分组,按照两次握手的协定,B认定为连接已经成功并发送返回成功信号,但是有可能的情况是信号丢失A无法接收到,这时出现的就是A在误以为B没有发送返回信号并且一直等待甚至怀疑对方B没有接收到请求信号,而B以为连接已经成功了,继续发送数据,但是A还在未成功建立连接,在等待的状态,它将忽略B所有发送过来的数据,而B发送数据后也在等待响应并没有接收到返回信号,造成了死锁。
四、如果已经建立了连接,但是客户端突然出现故障了怎么办?
在这种情况下,设计TCP/IP的人员同时在TCP设有一个保活计时器,显然,客户端如果出现了故障,服务器不能一直的等待下去,造成资源的浪费,所以服务器每一次收到客户端的请求都会重新复位这个计时器,时间通常是设置为2小时,若两小时后都没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。如若一连发送了10个探测报文任然没有反应,服务器就认为客户端出现了故障,紧接着就是关闭连接。
标签:cli sock 之间 端口 ack 复位 位置 image 四次挥手
原文地址:https://blog.51cto.com/11585002/2451387