• TCP的握手和挥手


    三次握手

    三次握手具体过程是什么?

    1. 客户端发送一个数据包

      • SYN置成1,表示希望建立连接

      • 这个包中的序列号是X

    2. 服务器收到客户端发来的数据包

      • 通过SYN得知这是一个建立连接的请求

      • 于是发送一个响应包

      • 并将SYNACK标志成1,

      • 假设发送包的序列号是是y

      • 确认序列号必须是x+1,表示收到了客户端发来的SYN请求

    3. 客户端收到服务端的响应包后需要进行确认

      • 确认包中将ACK置为1,并将确认序列号设置为y+1。表示收到了服务端的SYN请求

    image-20210202221736459

    为什么需要第三次握手?

    主要是要两个目的:信息对等防止超时

    信息对等

    image-20210202222020107

    防止超时

    即防止出现请求超时,导致脏连接。假设发生了下面的情况:

    • 客户端发送第一个请求,但是请求超时,报文依旧在网络上传输
    • 客户端发送了第二个请求,服务端成功接收到了
    • 服务端发送确认报文,连接成功
    • 传输数据完后,释放连接(两者就都不是SYN_CENT状态)
    • 之后,超时请求到达服务端,然后服务端接收,建立脏连接
    • 因为客户端不是SYN_CENT状态,直接丢弃服务端的确认报文,导致只有服务端单方面建立连接

    如果是三次握手的情况,服务端即使收到了超时请求报文,但是如果客户端迟迟不发送确认报文,导致连接超时,不会带来脏数据

    image-20210202223623114

    四次挥手

    四次挥手具体过程是什么?

    1. 客户端想要关闭连接,传递FIN信号给服务端
      • 客户端进入wait1状态
    2. 服务端应答了客户端,发送了ACK
      • 告诉客户端可以断开,但是你要等我处理完数据
      • 服务端进入close_wait状态
      • 客户端发送服务端的确认报文后会进入wait2状态
    3. 服务端处理完数据,发送FIN信号
      • 服务端进入了last_ack状态
    4. 客户端给服务端发送确认报文
      • 客户端进入time_wait状态
      • 服务端进入close状态
    5. 客户端经过2倍的MSL时间后,进入close状态

    为什么需要四次挥手?

    其实,我们可以把三次握手先看成次四次握手。

    因为在握手中,我们可以将确认报文和SYN信号一起发送过去,合二为一。

    但是挥手却不可以,因为这个过程客户端发送FIN信号后,虽然不可以发送数据,但是还可以接收服务端的数据。所以,不能合并

    image-20210202235102021

    为什么要等到2倍的MSL时间而不是直接关闭?

    MSL表示报文最大的生存时间,即任何报文在网络上存在的最长时间,超过这个时间就会被丢弃

    确保服务端成功接收到ACK报文

    假设碰到最坏的情况,服务端没有接收到ACK报文,服务端就需要重新发送SYN(一个MSL),服务端接收ACK(一个MSL)

    因此客户端为了确保对方能够收到ACK报文,所以必须要等待两被的MSL,然后关闭。

    确保新连接不接受过期数据包

    假设网络中有一个迟到的数据包,没有被服务端接收

    断开连接后,客户端又在相同的端口与服务器进行了一个新的连接

    那这个时候,迟到的数据包达到了服务端,服务端以为是新的客户端发送过来的消息。

    那么通过,经过2倍的MSL足足可以让两个方向上的数据包都被丢弃

    之后,建立的新连接就不过接收过期的数据包了

    如果对你我帮助记得给我一个推荐或点赞哦

    参考:

  • 相关阅读:
    UIActivityIndicatorView的使用
    几道面试题-考察JS的运用
    第六章-面向对象的程序设计(理解对象)
    webpack学习之——npm的安装依赖情况
    面向对象的编程(五)
    Javascript面向对象编程(四):非构造函数的继承
    面向对象的编程(三)—封装
    面向对象的编程(二)构造函数的继承
    面向对象的编程—封装
    第五章——引用类型
  • 原文地址:https://www.cnblogs.com/10134dz/p/14364965.html
Copyright © 2020-2023  润新知