美文网首页
面试 Tcp的三次握手和四次挥手

面试 Tcp的三次握手和四次挥手

作者: 许许如生hi | 来源:发表于2020-01-05 22:26 被阅读0次

    一、TCP的三次握手及相关问题


    1. TCP报文段首部格式


    TCP报文段首部格式
    • 序号seq(sequence number): 表示本报文段所发送的数据的第一个字节序号

      • 比如序号字段值是301,携带的数据共有100个字节,表示本报文段数据的第一个字节的序号是301
    • 确认号ack(acknowledge number):表示期望收到对方下一个报文段的第一个数据字节的序号

      • 比如 B收到A发来的报文中:
        • 序号的字段值是501(序号表示的是数据的第一个字节序号),数据长度是200
        • 则:B收到了序号为501-700的数据---->说明 B期待收到的下一个数据的序列号应该是 701
        • 于是:B把返回给A的报文中 确认号(ack)设置为701
    • 确认ACK(AXKnowlegment): 仅仅当ACK为1时该字段才有效,建立连接后所有传送的报文段都必须把ACK置1

    • 同步SYN(Synchronize Sequence Numbers) 在建立连接时用来同步序号

      • SYN=1 ACK=0 表示是连接请求报文段
      • SYN=1 ACK=1 表示对方同意建立连接
    • 终止FIN(FINis) 用来释放一个连接

      • FIN = 1时表示要求释放连接

    2. tcp三次握手详解


    三次握手
    • 客户端的初始状态是 closed
    • 服务端的初始状态是 listen

    2.1 第一次握手


    客户端给服务端发送请求报文段

    • 此报文段的同步位 SYN = 1 ,表示这是一个请求报文段
    • 随机生成一个序列号 seq = x;
      • 随机生成一个序列号是为了网络安全,如果序列号不是随机的容易被黑客获取到初始序列号
    • 客户端的状态变成: SYN_SEND(同步已发送)
    • 这个报文段不能携带数据

    2.2 第二次握手


    服务端同意建立连接

    • SYN = 1 , ACK = 1 表示同意建立连接
    • 确认号是 ack = 1 ;
    • 随机生成一个初始序号 seq = y;
    • 不携带数据
    • 服务端状态变成 SYN_RCVD(同步已收到)

    2.3 第三次握手


    客户端再次向服务端给出确认

    • AXK = 1
    • 确认号 ack = y + 1 ; seq = x + 1 ;
    • 客户端状态变成 ESTABLISHED
    • 当服务端收到确认后也变成 ESTABLISHED

    3. 为什么要三次握手,三次握手功能

    三次握手功能生动解释
    • 第一次握手可以确认: 客户端发送数据功能正常 (A发出信号)
    • 第二次握手可以确认: 服务端接收发送功能均正常(B确认喜欢A,并发出信号)
    • 第三次握手可以确认: 客户端接收功能正常(第三个阶段才能确认A也喜欢B,第一个阶段并不能确认A喜欢B,第一个阶段A只是问了B)

    4. 半连接队列和全连接队列


    [图片上传失败...(image-e1545c-1578234377605)]

    • 第一次受到client的SYN之后,server处于SYN_RCVD状态,此时双方还没有完全建立连接,server会把这种状态下的请求连接放在一个队列里,称为半连接队列
    • 已经完成三次握手之后,建立起的连接会放在全连接队列中,如果队列满了可能会出现丢包,这样的队列称为全连接队列
    • server发送SYN和ACK包的重传:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s......

    5. 三次握手中可以携带数据吗


    第一次和第二次握手不可以携带信息,第三次可以携带信息,前两个阶段不可以携带信息。因为第三次握手的时候客户端才是ESTABLISHED状态,就上面那个生动的图来讲,只有第三次握手你确定了互相喜欢才可以携带一些信息(比如一起看电影、约会)

    6. SYN 和 SYN 攻击


    SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,常用假冒的IP或IP号段发来海量的请求连接的第一个握手包(SYN包),被攻击服务器回应第二个握手包(SYN+ACK包),因为对方是假冒IP,对方永远收不到包且不会回应第三个握手包。导致被攻击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,塞满TCP等待连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来。


    TCP的四次挥手及相关问题


    1. 四次挥手详解


    四次挥手

    1.1 第一次挥手


    client发出连接释放报文段

    • FIN = 1 (要求释放连接)
    • seq = u 前面传输数据的最后一个字节加1
    • client状态:FIN_WAIT1(终止等待1、等待server确认)

    1.2 第二次挥手


    server接收到释放报文段后发出确认 (这时候 client ---> server方向连接断了)

    • ACK = 1
    • ack = u + 1 ;
    • seq = v ; 已经发送的数据的最后一个字节序号加1
    • server 进入CLOSE_WAIT(等待关闭状态)
    • client 进入FIN_WAIT2(终止等待2状态),等待server发出释放确认报文段
    • 这时候CLIENT-SERVER的连接释放了,这时候与的TCP处于办关闭状态(half-close),这时候client已经没有数据要发了,但是这时候server还有可能向client发送数据

    1.3 第三次挥手


    这时候server发出连接释放报文段(想让 server--->client方向连接断掉)

    • FIN = 1;
    • 重复发送确认报文段: ACK = 1; ack = u + 1;
    • server状态: LAST_ACK 等待A确认

    1.4 第四次挥手


    client同意与server断开连接

    • ACK = 1;
    • client状态: TIME_WAIT 在2MSL之后变成CLOSED
    • server状态: CLOSED

    1.5 通俗解释一下


    四次挥手

    2. 为什发送端需要等待 2MSL后关闭


    MSL:(Maximum segment lifetime)最长报文寿命
    为什么要等待两个msl?

    • 1.保证client发送的ACK可以成功到达server,如果client发送完就close了,万一报文丢失,server收不到client发来的ACK,就会超时重新进行第三次挥手,这个时间就是2MSL:即:超时等待时间+再次进行第三次挥手的事件

    • 2.防止“已失效的连接请求报文段”出现在本连接中。
      客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段


    3. 为什么第二次挥手和第三次挥手不能合并


    细心的同学发现,所谓四次挥手中的第二次和第三次就是把握手中的第二次拆来了。为什么不能合并?

    • 因为挥手过程和握手过程不同,前两次握手是不携带数据的只处理连接问题。挥手不仅要解决连接问题,还要解决数据传输问题,第二次挥手后,client只是不能发送数据了,但是并不说明不能接受数据。server可能还有数据要给client。所以二三两次不可以合并

    引用博客


    相关文章

      网友评论

          本文标题:面试 Tcp的三次握手和四次挥手

          本文链接:https://www.haomeiwen.com/subject/ipacactx.html