咱们对TCP三次握手耳熟能详,那么你知道TCP四次挥手过程吗?bash
1、前言
唐代诗人李商隐在《无题》诗中写到:“相见时难别亦难,东风无力百花残”,表达了本身与心爱之人相见之难、离别之苦。若是把这句诗用在形容TCP链接的创建与释放过程,也很贴切。咱们知道TCP创建链接时须要三次握手,而TCP链接释放则须要四次挥手,是否是很像诗中描述的意境——见面很难,分开更难。 若是你还不清楚相见之难—TCP三次握手过程,能够看个人上篇博文TCP三次握手原理,这样便于你更好理解TCP四次挥手释放链接的过程。网络
2、TCP四次挥手过程
TCP四次挥手指的是TCP链接释放过程, 不一样于TCP链接创建时的三次握手过程,TCP链接释放过程更加复杂。在进入正题前,咱们先回忆下TCP协议的两个重要特色:post
- TCP协议面向链接:应用在使用TCP协议通信时,必需要先创建TCP链接。
- TCP链接是双向通讯:通讯的两端是对等的,既能发送数据,也能接收数据,就向咱们打电话时同样,既能说也能听。
这两个重要特色决定了TCP链接的释放过程。下面咱们一块儿来看下TCP四次挥手的过程都发生了什么。为了更好的理解,简单的画了下TCP四次挥手示意图以下: spa
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状态,开始下一个链接。
上面就是TCP链接的释放过程,若是你以为比较复杂能够简单理解为这样:3d
client——> server: 数据传输完毕,请求释放链接!
server——> client: 收到,能够释放链接!等我处理完毕会通知你
server——> client: 个人数据也发送完毕!能够释放链接
client——>server: 收到!已释放链接,Bye
复制代码
3、小细节
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故障了,直接关闭链接。 code
4、总结
为了更清晰看到TCP各类链接之间关系,最后附上一张TCP有限状态机图: cdn