zoukankan      html  css  js  c++  java
  • 第8章 传输层(7)_TCP连接管理

    7. TCP连接管理

    7.1 TCP的连接建立

    (1)三次握手

     

      ①三次握手过程

        A.第1、2次握手,数据包的SYN均为1,表示用于同步。即第1次客户端发起请求,并将自己的连接参数如接收窗口大小、MSS和是否支持SACK等告知服务器。第2次连接是服务器收到连接请求后作出确认,同时其自己的连接参数告知客户端,这主要是出于双向通信的需要)。因此SYN=1表示,这两个数据包主要用于协商和同步通信双方的连接参数)。ACK=1表示是一个确认包。ack表示确认的数据包序号。

        B.第3次握手用于告知服务器端,客户端己收到确认,可以正式开始通信。

      ②TCP连接状态(查看的命令:netstat -an

        A.服务器启用后,会进入LISTEN状态,监听客户端连接。

        B.当客户端发出连接请求后进入SYN-SEND状态。服务器收到请求后进入SYN-RCVD状态,然后发一个确认包给客户端。

        C.客户端收到确认包以后,创建TCP连接并进入ESTABLISHED状态,同时通知服务器己收到确认包。

        D.服务器收到客户端和通知后,也创建TCP连接并进入ESTABLISHED,于是双方TCP连接建立完成,可以正式通信。

    (2)为什么需要三次握手?防止失效的连接请求突然又到达服务器!

     

      ①场景假设:客户端发出的第1次连接请求,由于网络延时的原因直至客户端连接超时,该请求还未到达服务器端。因此,这个连接请求在客户端这里就会被作废。于是发送第2个连接请求。

      ②如果只采用两次握手

        A.当服务器收到第2次的连接请求后,会发送确认告诉客户端己收到请求。由于采用的是两次连接,此时就会创建一个新的Socket来服务客户端

        B.客户端收到服务端的确认后,也创建与服务器通信的TCP连接。于是双方可以正式通信了。

        C.当双方TCP连接建立起来以后。然后那个在网络上延时的第1个连接请求到达了服务器。服务器收到这个连接请求后,由于两次握手机制依然会创建一个用来服务客户端的TCP连接,并发一个确认给客户端。但由于第1次连接请求在客户端看来己失效,相当于客户端会认为我并没有发出连接请求,而服务器莫名其妙地发一个确认给自己,因此就会直接丢弃这个确认包。但对于服务端来讲,连接己经建立了,可以正常通信。就会一直在那等着客户端给自己发数据,这对服务器来说是一种严重的资源浪费。

      ③如果采用三次握手主要分析这个延时的请求会被如何处理?因为第2次连接请求是正常的TCP通信的过程!)

        A.第1次连接请求(在网络上被延时)突然到达服务器(第一次握手)。

        B.服务器并不马上建立TCP连接,而是通知客户端收到了该请求。(第二次握手)

        C.当客户端收到这个“确认”以后,由于第1次连接请求在客户端看来己经失效,所以会认为自己并没有发出连接请求,就会直接丢弃这个“确认包”服务器由于没有收到对“确认的确认”就不会为客户端创建TCP连接,这可以防止服务端资源的浪费。

    7.2 TCP连接释放

    (1)四次挥手过程

     

      ①第1次挥手:客户端(也可以是服务端)主动向服务端发送一个FIN报文段,然后进入FIN_WAIT_1状态。此FIN报文段的意思表示客户端需要发送的用户数据己发送完毕,不再有用户数据需要发送给服务器了。这时的TCP处于半关闭状态,即只有一方向另一方发送用户数据。

      ②第2次挥手:服务器收到客户端发送的FIN报文段,通知其高层的应用程序。然后发送确认给客户端,客户端收到后进入FIN_WAIT_2状态继续等待。因为服务端可能还有数据没发完,让客户端继续等服务端的通知。而服务端发送对FIN报文的确认完,会进入CLOSE-WAIT状态等待从B向A的数据传完。

      ③第3次挥手:当服务端向客户端的数据传输完以后,高层应用程序会通知TCP。然后TCP发送FIN报文给客户端通知其也没有用户数据需要传输,可以关闭连接了。同时服务器进入LAST_ACK状态。

      ④第4次挥手:客户端收到服务器发送的FIN报文,向服务器发送ACK报文,然后客户端进入TIME_WAIT状态。服务器收到客户端的ACK报文段后,就关闭连接。此时,客户端等待2MSL(2倍的最长报文段时间)后就关闭连接了。

    (3)为什么客户端在TIME-WAIT状态必须等待2MSL的时间?

      保证A发送的最后一个ACK报文段能够到达B。这个ACK报文可能丢失,因而B可能在超时以后重传这个FIN+ACK报文给A,而A就能在2MSL时间内收到这个重传的FIN+ACK报文。接着A重传一次确认,并重启2MSL计时器。如果A在TIME-WAIT不等待一段时间,而是在发送完ACK后立即释放连接,那么就无法收到B重传的FIN+ACK报文从而导致B不能按正常步骤进入CLOSED状态。

    (4)保活器计时(Keepalive Timer)

      ①如果客户端突然出现故障,这时并没有机会通知服务器。为防止服务器无谓地等下去。就需要用保活计时器。

      ②服务器在每收到一次客户端发来的数据,就重置保活计时器(通常是2小时)。若在规定的时间内没有收到客户的数据服务器就会发送一个探测报文段,以后每隔(75秒)发一次,如果一连发送10个探测报文仍无客户的响应。就认为客户端出了故障,接着就关闭连接。

    7.3 实战:查看TCP连接/释放的数据包

    (1)抓包分析TCP连接过程的数据包(以客户端给服务器的第1个数据包为例)

     

      ①第1次握手的数据包:seq=x(0),SYN=1,ACK= 0,ack= y(0)(在此次中该值无效),以及一些协商参数(如客户端的接收窗口大小,TCP选项部分包含了最大报文段长度(MSS)、是否支持选择确认)

      ②第2次握手的数据包:seq=y(0),SYN=1,ACK=1(表示是一个确认包),ack=x+1(1)以及为了支持双向通信的一些协商参数(如服务端的接收窗口、MSS、是否支持SACK等)

      ③第3次握手的数据包:seq=x+1(1),SYN=0,ACK=1,ack=y+1(1)

    (2)抓包分析TCP释放过程的数据包

     

      ①释放数据包的TCP首部有FIN标志。②可在命令行中通过netstat –n查看TCP活动的连接及状态

    7.4 实战:SYN和LAND攻击

    (1)SYN攻击

     

      ①在A计算机上安装SYN攻击器软件。该软件会向B发送TCP连接请求。

      ②但由于SYN伪造了一个TCP请求报文,将源地址改为其他的主机地址(假设是x)。这将导致B计算机把对连接请求的确认报文给x计算机。

      ③由于x计算机根本没有向B机请求连接,因此会直接丢弃数据包。但B并不知道会一些等待x机的确认,以便完成TCP连接。如果A大量发送这样的TCP请求,无疑将造成B计算机资源的极大浪费(见抓包图) 

    (2)LAND攻击

     

      ①与SYN攻击类似,LAND将一个TCP请求报文中的源地址改成目标主机地址

      ②这样会导致B计算机在收到请求报文后又给自己发了一个确认包。这个攻击比SYN攻击更利害,可能会直接导致B的崩溃。

  • 相关阅读:
    idea设置全局ignore
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistributable. Please ins
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistr
    kafka 删除 topic
    java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
    Centos中使用yum安装java时,没有jps的问题的解决
    Spring 整合Junit
    Spring纯注解配置
    Spring 基于注解的 IOC 配置
    打印java系统的信息
  • 原文地址:https://www.cnblogs.com/5iedu/p/7262719.html
Copyright © 2011-2022 走看看