zoukankan      html  css  js  c++  java
  • TCP三次握手、四次挥手

    一、三次握手

           TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立可靠连接,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大

    小信息。

                                     

           第一次握手:建立连接。客户端发送连接请求报文段,将SYN设置为1,Seq设置为x,然后,客户端进入SYN_SEND状态,等待服务器的确认。

      第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个报文段进行确认,设置ACK为x+1(Seq+1),同时,服务器自身还要发送SYN请求信息,将SYN设置为1,Seq设置为y。服务器将上述SYN、ACK、Seq放置在一个报文段中,一起发送给客户端,服务器端进入SYN_RECV状态。

      第三次握手:客户端收到服务器端的报文段(SYN、ACK、Seq)。客户端收到服务器端的报文段后向将ACK设置为y+1,向服务器端发送ACK报文段,这个报文段发送完毕后,客户端和服务器端都进入ESTABLISHED状态,三次握手完成。

     

    二、四次挥手

      当客户端与服务器在通过三次握手建立TCP连接,传输完数据之后,将会断开TCP连接。断开TCP连接的过程就是四次挥手。

                                                               

      第一次挥手:主机1(主动断开方)主动断开连接(可以是客户端,也可以是服务器端),设置Seq为u,ACK为Z,发送给主机2被动断开方一个FIN报文段,然后主机1进入FIN_WAIT_1状态,这表示主机1已经没有数据要发送给主机2了。

      第二次分手:主机2收到主机1发送的FIN报文段,将Seq设置为z,ACK为x+1(Seq+1),向主机2回应一个ACK报文段,主机2由CLOSED_WAIT变为CLOSED_OK,主机1收到回应报文后由FIN_WAIT_1变为FIN_WAIT_2;

      第三次分手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2由CLOSED_OK进入LAST_ACK状态。

      第四次分手:主机1收到主机2的FIN报文段后,向主机2发送ACK报文段,然后主机1由FIN_WAIT_2进入TIME_WAIT状态。主机2收到主机1的ACK报文段以后,关闭连接,此时主机1等待2MSL后如果还没有收到回复,那么就证明服务器端已经正常关闭,主机1也就可以关闭连接了,客户端和服务器端都进入CLOSED状态。

    三、相关问题

      1、为什么建立连接要三次握手?

      防止已经失效的连接请求报文段突然又传送到了服务器端。例如:Client发送的第一个连接请求报文段并没有丢失,但是由于某些原因没有及时到达Server,以致延误到Client连接释放以后的某个时间才到达Server。这个报文段在Client端早已经失效,但是Server端并没有,于是Server将会向Client端发送出确认报文段,同意建立连接。假设没有三次握手,那么只要Server发出确认,新的连接就会建立。但是现在Client并没有发出建立连接的请求,也就不会搭理Server的确认,更不会像Server发送ACk报文。而Server却认为连接已经建立,就会一直等待Client发来数据,这样Server的资源就会白白的浪费。现在我们采用了三次握手,那么在同样的情况下,Client不会向Server的确认发出确认,Server由于没有收到Client的确认,就知道Client没有请求建立连接。

      2、为什么关闭连接要四次挥手?

      TCP连接是面向连接的、可靠的、基于字节流的传输层协议,TCP是全双工模式。这就意味着当主机1发出FIN报文段时,只是表明主机1已经没有数据要发送了,但是主机1可以接收来自主机2的数据,但主机2返回ACK报文段时,表明主机2已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1,当主机2也发送FIN报文段时,表明主机2也没有数据要发送了,连接双方就中断本次TCP连接。

      3、问什么主动断开方还要等待2MSL?

      MSL:报文段最长生存时间,它是任何报文段被丢弃前在网络内的最长时间。

      ①保证TCP协议的全双工连接能够可靠关闭。如果主机1直接CLOSED,那么由于IP协议的不可靠性或者其他的网络原因,导致主机2没有收到主机1最后的ACK确认,那么主机2就会在超时后重新发送FIN,但是主机1已经CLOSED,就找不到与重发FIN对应的连接。故主机1不会立刻CLOSED,而保持TIME_WAIT,如此如果再次收到FIN报文段时,能够保证对方收到ACK,最后确认关闭连接.

      ②保证这次连接的重复数据段从网络中消失。如果主机1直接CLOSED,然后又向主机2发起一个新的连接,我们无法保证这个新的连接与刚关闭的连接端口号是不同的,即新旧两个连接的端口号可能使相同的。那么如果上一次连接的某些数据还在网络上,这些延迟数据在新连接建立后才到达主机2,由于新旧连接的端口号相同,TCP协议就会认为那个数据时新连接的,这样两次连接的数据包就混在一起了。所以在等待2MSL后,即使真有数据滞留,也将会在2MSL内全部消失。

      4、什么是synflood攻击?

        synflood发生在建立连接的三次握手过程中。正如问题1中所说,虽然在Client没有向Server的确认发出确认,但是Server的连接并不是立马取消,这就是产生synflood攻击的原因。假设一个Client向Server发送了SYN报文后突然死机或者掉线,那么Server在发出SYN+ACK应答报文后是无法收到Client的ACK报文的。这种情况下Server一般会重试(再次发送SYN+ACK)并等待一段时间后丢弃这个未完成的连接,这段时间通常称为SYN Timeout,一般来说这个事件时分钟级别的(大约30s-2min)。一个Client出现异常导致Server一个线程等待1分钟并没有什么,但是如果恶意攻击大规模地模拟这种情况,Server将会为了维护一个非常大的半连接而消耗非常多的资源,即使简单的保存并遍历也会消耗非常多的CPU时间和内存,糟糕的是还需要对这个列表中的IP进行SYN+ACK的重试。最后,如果Server的TCP/IP栈不够大,往往使堆栈溢出崩溃,即使Server系统足够强大,也将忙于处理攻击者伪造的TCP请求而无暇处理正常的请求(占比小)。此时,从正常Client的角度看,将会认为服务器失去响应,这种情况即被称为synflood攻击(syn洪水攻击)。

     

  • 相关阅读:
    Spring security中的BCryptPasswordEncoder方法对密码进行加密与密码匹配
    Eclipse导入SpringBoot项目pom.xml第一行报错Unknown error
    分库分表理论概述
    什么是乐观锁,什么是悲观锁
    oracle中的索引查看
    手动实现tail
    KNN理论
    矩阵以及向量
    numpy常用的几个小函数
    线性回归
  • 原文地址:https://www.cnblogs.com/QullLee/p/8542205.html
Copyright © 2011-2022 走看看