zoukankan      html  css  js  c++  java
  • TCP三次握手与四次挥手过程

    转载https://blog.csdn.net/qq_35216516/article/details/80554575

    首先,客户端与服务器均处于未连接状态,并且是客户端主动向服务器请求建立连接:


    客户端将报文段中的SYN=1,并选择一个seq=x,(即该请求报文的序号为x)  将这个报文发送到服务器。此时,客户端进入同步已发送状态(SYN-SEND).SYN报文段不能携带数据,但是要消耗掉一个序号。
    服务器收到请求报文后,若同意建立连接,则回复报文中,SYN=1,ACK=1,并选择一个seq = y,且报文中确认号为x+1,序号为y   .此时服务器进入同步已接收状态(SYN-RCVD)


    客户端收到服务器的同步确认后,对服务器发送确认的确认。将ACK=1,确认号为y+1,而报文首部的序号为x+1,将该报文发出后,客户端进入已连接状态(ESTABLISHED)。


    服务器收到客户端的确认后,也进入已连接状态。
    以上即三次握手




    为何使用三次握手机制:
    假设如下异常情况:

    客户端向服务器发送了第一条请求报文,但是该报文并未在网络中被丢弃,而是长时间阻滞在某处,而客户端收不到服务器确认,以为该报文丢失,于是重新发送该报文,这次的报文成功到达服务器,如果不使用三次握手,则服务器只需对该报文发出确认,就建立了一个连接。而在这个连接建立,并释放后,第一次发送的,阻滞在网络中的报文到达了服务器,服务器以为是客户端又重新发送了一个连接请求(实际上在客户端那里,该连接早已失效),就又向客户端发送一个确认,但客户端认为他没有发送该请求报文,因此不理睬服务器发送的确认,而服务器以为又建立了一个新的连接,于是一直等待A发来数据,造成了服务器资源的浪费,并且会产生安全隐患。因此,若使用三次握手机制,服务器发送了该确认后,收不到客户端的确认,也就知道并没有建立连接,因此不会将资源浪费在这种没有意义的等待上。


    TCP连接的释放(四次挥手)

    连接的释放较连接的建立复杂。


    现假设客户端与服务器均处于连接建立状态,客户端主动断开连接:


    1.客户端向服务器发送FIN报文:FIN=1,序号seq=上一个最后传输的字节序号+1=u,发送后,客户端进入FIN-WAIT-1状态。


    2.服务器接收到该报文后,发送一个确认报文:令ACK=1,确认序号ack = u+1,自己的报文序号seq=v,发送后,服务器进入CLOSE-WAIT状态。

    3.此时TCP连接进入连接半关闭状态,服务器可能还会向客户端发送一些数据。

    4.客户端收到来自服务器的确认之后,进入FIN-WAIT-2状态。等待服务器发送连接释放报文。

    5.如果服务器已经没有要发送的数据,则释放TCP连接,向客户端发送报文:令FIN=1,ACK=1,确认号ack =u+1,自己的序号seq = w(w可能等于v也可能大于v),服务器进入LAST-ACK状态。

    6.客户端收到服务器的连接释放报文后,对该报文发出确认,令ACK=1,确认号ack=w+1,自己的序号seq=u+1,发送此报文后,等待2个msl时间后,进入CLOSED状态。

    7.服务器收到客户端的确认后,也进入CLOSED状态并撤销传输控制块。

    客户端状态变化:未连接----->SYN-SEND----->ESTABLISHED----->FIN-WAIT-1----->FIN-WAIT-2----->TIME-WAIT----->CLOSED

    服务器状态变化:未连接----->SYN-RCVD----->ESTABLISHED----->CLOSE-WAIT----->LAST-ACK----->CLOSED

    通俗描述3次握手就是

    A对B说:我的序号是x,我要向你请求连接;(第一次握手,发送SYN包,然后进入SYN-SEND状态)

    B听到之后对A说:我的序号是y,期待你下一句序号是x+1的话(意思就是收到了序号为x的话,即ack=x+1),同意建立连接。(第二次握手,发送ACK-SYN包,然后进入SYN-RCVD状态)

    A听到B说同意建立连接之后,对A说:与确认你同意与我连接(ack=y+1,ACK=1,seq=x+1)。(第三次握手,A已进入ESTABLISHED状态)

    B听到A的确认之后,也进入ESTABLISHED状态。

    描述四次挥手就是:

    1.A与B交谈结束之后,A要结束此次会话,对B说:我要关闭连接了(seq=u,FIN=1)。(第一次挥手,A进入FIN-WAIT-1)

    2.B收到A的消息后说:确认,你要关闭连接了。(seq=v,ack=u+1,ACK=1)(第二次挥手,B进入CLOSE-WAIT)

    3.A收到B的确认后,等了一段时间,因为B可能还有话要对他说。(此时A进入FIN-WAIT-2)

    4.B说完了他要说的话(只是可能还有话说)之后,对A说,我要关闭连接了。(seq=w, ack=u+1,FIN=1,ACK=1)(第三次挥手)
    5.A收到B要结束连接的消息后说:已收到你要关闭连接的消息。(seq=u+1,ack=w+1,ACK=1)(第四次挥手,然后A进入CLOSED)
    6.B收到A的确认后,也进入CLOSED。

     
     
    最简单的理解
    一:建立TCP连接:三次握手协议
        
    客户端:我要对你讲话,你能听到吗;
    服务端:我能听到;而且我也要对你讲话,你能听到吗;
    客户端:我也能听到。
    …….
    互相开始通话
    ……..    
     
     
    二:关闭TCP连接:四次握手协议
     
    客户端:我说完了,我要闭嘴了;
    服务端:我收到请求,我要闭耳朵了;
    (客户端收到这个确认,于是安心地闭嘴了。)
    …….
        服务端还没倾诉完自己的故事,于是继续唠唠叨叨向客户端说了半天,直到说完为止
    …….
    服务端:我说完了,我也要闭嘴了;
    客户端:我收到请求,我要闭耳朵了;(事实上,客户端为了保证这个确认包成功送达,等待了两个最大报文生命周期后,才闭上耳朵。)
    (服务端收到这个确认,于是安心地闭嘴了。)
  • 相关阅读:
    Hibernate第二天:Hibernate的一级缓存、其他的API
    Hibernate第一天(Hibernate的环境搭建、Hibernate的API、Hibernate的CRUD)
    数据结构基础(一)数组,矩阵
    MyEclipseSVN插件百度云下载
    修改CentOS主机名
    Word中增加仿宋GB-2312字体
    Linux系统常用基本命令总结
    SpringBoot视频教程 百度云
    VM虚拟机中linux centOS 联网单网卡配置教程
    Java正则表达式匹配日期及基本使用
  • 原文地址:https://www.cnblogs.com/gaodi2345/p/11707223.html
Copyright © 2011-2022 走看看