• TCP三次握手和四次挥手


    一、概述

    • 传输连接就有三个阶段,即:连接建立、数据传送和连接释放。

    • 连接建立过程中要解决以下三个问题:

      要使每一方能够确知对方的存在。

      要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。

      能够对运输实体资源(如缓存大小,连接表中的项目等)进行分配。

    二、 三次握手

    TCP连接建立时,通过三次握手实现

    1、三次握手流程

    image-20210110145115993

    • 第一次握手:A先向B发送一个同步数据包(报文)。

      在数据包的TCP首部中:标志位:同步SYN为1,表示这是一个请求建立连接的数据包;

      ​ 确认标记位ACK为0,说明该数据包的确认号无效,所以该标志位可省略;

      ​ 序号Seq=x,x为所传送数据的第一个字节的序号。

    • 第二次握手:B收到A发送的第一个数据包后,决定是否同意连接,若同意,则B发送一个数据包进行回应

      在数据包的TCP首部中:标志位:同步SYN=1;

      标志位:确认ACK=1;

      序号seq=y;表示B给A的第一个数据字节的序号

      确认号ack=x+1; 表示已经收到A发送的x个字节数据,并告诉A下次应从数据的第x+1个字节开始发送。

      只有确认位ACK为1时,确认号才有效

    • 第三次握手:A收到B的确认之后,再给A发送一个数据包。

      在数据包的TCP首部中:已经没有有效的标志位:同步SYN了(即SYN=0),表示双方已同意建立连接;

      标志位确认ACK=1,表示收到B的确认数据包;

      序号seq=x+1; 表示A给B的第一个数据字节的序号

      确认号ack=y+1,表示收到了B发送y字节数据,并告诉B下次应从数据的第y+1个字节开始发送。

    2、三次握手建立TCP连接过程的各状态

    image-20210110145127337

    A发出请求建立连接的数据包之后进入SYN-SENT状态,表示发送了请求建立连接的同步数据包。

    B收到A发出的请求建立连接的数据包之后,结束LISTEN状态,进入SYN-RCVD状态并向A发出确认数据包。

    A收到确认数据包之后,结束SYN-SENT状态,进入ESTABLISHED状态,并向B发送确认数据包。

    B收到A的确认数据包之后,结束SYN-RCVD状态,进入ESTABLISHED状态。

    A与B都进入ESTABLISHED状态之后,开始传输数据,由此完成三次握手。

    • 测试

      SYN-SENT==》 通过访问一个不存在的地址,自己一直收不到确认连接状态,就会一直处于SYN-SENT状态

    image-20210110145244470

    3、为什么需要三次握手?

    ​ 如果是两次握手,即A发给B要建立连接,B回复确认信息。会有以下问题:(syn攻击)

    1、当A给B发建立请求的数据包时,由于网络原因,B还没有收到 ==》 A以为超时了

    2、A再给B发建立请求的数据包,这次很快,B收到了。并且回复确认信息。两台主机建立了连接

    3、此时A发的第一个建立连接的数据包终于到了B那里,B以为是再次建立连接,于是又发送确认信息

    4、A收到确认信息,一看我已经建立连接了,所以就丢掉不管。 但是B不知道,以为建立了连接,会有A的数据。但A永远也不会发送数据过来

    ​ 第三次握手(第三个数据包)作用在于,告诉B计算机,B第二次握手发给A的确认数据包A收到了,是有效的。避免B计算机等待造成资源浪费。随后A与B可进行下一步的通信。

    4、抓包验证

    网页访问 https://www.cnblogs.com/

    该网站的ip地址为:

    image-20210110145556544

    以下为抓包结果:(可以看到经过三次握手后,建立了连接。后面就可以发送消息了)

    image-20210110145605985

    三、四次挥手

    1、四次挥手过程

    TCP连接释放,通过四次挥手实现

    所谓的四次挥手即TCP连接的释放(解除)。连接的释放必须是一方主动释放,另一方被动释放。

    ​ 数据传输结束后,通信的双方都可主动释放连接。下为A主动释放TCP连接。

    image-20210110145857199

    • 第一次挥手:首先A向B发送连接释放请求报文(数据包),并停止发送数据。

      在连接释放报文(数据包)的TCP首部中:标志位:终止FIN=1,意味着A要主动释放A—>B的TCP连接;

      ​ 序号位seq为u,u值由A指定。随后等待B的确认。

      此时A的状态变为FIN-WAIT-1。B还没有收到数据包,状态还是ESTABLISHED

    • 第二次挥手:B收到连接释放报文之后,给A发送确认报文

      此时TCP服务器进程通知高层应用进程,这样从A到B这个方向上的连接就释放了,TCP连接处于半关闭状态。

      此时A没有数据要发给B了,但是B还有数据要发送给A,A仍可以接收。

      在确认报文的TCP首部中:标志位:确认ACK=1,表示收到了A发送的数据包,同意A释放连接;‘

      序号位seq=v,v值由B指定;

      确认号ack=u+1,表示已经收到A发送的u个字节数据,并告诉A下次应从数据的第u+1个字节开始发送,下面同理;此时B还可以向A传输数据。

      B的状态变为CLOSE_WIAT。A收到确认报文后,状态变为FIN-WAIT-2

    ====前两次挥手 A到B这条连接就断了(B可能还要向A发送数据)=

    • 第三次挥手:B向A发送释放连接请求

    在确认报文的TCP首部中:标志位:确认ACK=1,表示B已经把需要发给A的数据发完了;

    标志位:终止FIN=1,意味着B要释放B—>A的TCP连接;

    序号seq=w,w值由B指定;

    确认号ack=u+1;此后B不再向A发送数据,但能接收数据。

    B的状态变为LAST-ACK。

    • 第四次挥手:A收到B的连接释放报文段后,向B发出确认报文。

      在确认报文的TCP首部中:标志位:确认ACK=1,表示收到B的确认报文,并同意B释放连接;

      序号seq=u+1;

      确认号ack=w+1;

      A的状态变为TIME-WAIT。B收到确认报文后,状态变为CLOSED

      A在经过2msl后,状态也变为CLOSED

    由此通过四次挥手释放了TCP连接。

    以下为动态过程:

    Peace

    2、为什么是三次握手和四次挥手?

    ​ 三次握手中第二次握手传递了SYN=1和ACK=1。表示需要服务端B要和客户端A建立连接,并且确认收到了客户端A的连接请求。即建立连接报文和确认报文是一起传过去的。

    ​ 四次挥手中ACK确认报文和FIN结束报文在第二次挥手(B向A确认收到A发来的结束请求)和第三次挥手(B向A发送结束请求)中分别发送。为什么释放连接的时候需要分开传输?

    • 建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。(此时B是没有处理任何事的)

    • 释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。 (此时B正在处理自己的事,所以不能立刻结束B到A的连接)

    3、为什么客户端在TIME-WAIT阶段要等2MSL?

    为了确定服务端是否收到了客户端发的确认信息

    MSL指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。

    2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。

    ​ 当客户端发出确认信息后,并不能保证服务端已经收到了确认数据。所以客户端在发送完确认信息后,会设置一个2MSL的计时器。

    • 服务器端在1MSL内没有收到客户端发出的ACK确认报文,就会再次向客户端发出FIN报文;
    • 如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端再次向服务器端发出ACK确认报文,计时器重置,重新开始2MSL的计时;
    • 否则客户端在2MSL内没有再次收到来自服务器端的FIN报文,说明服务器端正常接收了ACK确认报文,客户端可以进入CLOSED阶段,完成“四次挥手”。

    所以,客户端要经历时长为2SML的TIME-WAIT阶段;这也是为什么客户端比服务器端晚进入CLOSED阶段的原因

    4、抓包演示四次挥手

    image-20210110151808521

    参考链接:

    https://www.cnblogs.com/GoForMyDream/p/8707813.html

    https://www.cnblogs.com/AhuntSun-blog/p/12037852.html#4691774


    如果本篇博客有任何错误和建议,欢迎大佬们批评指正

    我是知逆,我们下期见

  • 相关阅读:
    工作一年感想
    launcher项目踩坑小结(1)
    滕王阁序
    PC端/移动端常见的兼容性问题总结
    Java中逻辑&和短路&&,逻辑|和短路||的区别
    Linux常用指令和系统管理命令总结
    Ajax学习笔记
    js放大镜特效
    《Python for Data Science》笔记之着手于数据
    Python2&3学习中遇到的坑
  • 原文地址:https://www.cnblogs.com/mercurytan/p/14258440.html
Copyright © 2020-2023  润新知