欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

TCP三次握手、四次挥手

程序员文章站 2022-04-18 19:00:14
一、三次握手 TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立可靠连接,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大 小信息。 第一次握手:建立连接。客户端发送连接请求报文段,将SYN设置为1,Seq设置为x,然后,客户端进 ......

一、三次握手

       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连接的过程就是四次挥手。

                                    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洪水攻击)。