• 【计算机网络】TCP为什么需要3次握手


    计算机网络——TCP建立连接的3次握手

    TCP报文段首部

    大致的流程想必大家并不陌生,我们先具体分析一下它这三次传输 首部都包含了哪些信息。

    我们先来认识一下TCP报文段的首部都有哪些字段是需要用到的:

    • s e q seq seq序号

      ➢ TCP会给每一个字节都编上一个序号,而序号字段的值则是当前报文段所发送数据报的第一个字节的序号。

      ➢ 假设当前发送的数据序号为 1 − 200 1-200 1200,那么序号字段的值就是 1 1 1

    image-20220618212712401

    • a c k ack ack确认号

      ➢ 确认号的值是期望收到对方下一个报文段的数据的第一个字节的序号

      ➢ 假设上方举例 发送的数据序号为 1 − 200 1-200 1200:发送方为 A A A,接收方为 B B B,那么此时 B B B 返回的确认号即为 201 201 201

    image-20220618213050835

    一共需要用到两个校验位 ( b i t ) (bit) (bit),分别是 S Y N SYN SYN A C K ACK ACK

    • S Y N SYN SYN同步位

      ➢ 当同步位被置为 1 1 1 时,就是在建立连接

      ➢ 当同步位被置为 0 0 0 时,连接建立成功

    image-20220618210440802

    • A C K ACK ACK确认位

      ➢ 当确认位被置为 1 1 1 时,说明确认号字段有效

      ➢ 当确认位被置为 0 0 0 时,确认号无效

    image-20220618210406252

    注意:确认号 a c k ack ack 是小写的,确认位 A C K ACK ACK 是大写的。

    TCP建立连接

    A A A 为客户端 ( C l i e n t ) (Client) (Client) B B B 为服务端 ( S e r v e r ) (Server) (Server)

    第一次握手

    image-20220618214704012

    此时主机 A A A 向主机 B B B 第一次发出请求(刚开始它的报头肯定有源端口、目的端口等,但这不是我们关注的重点),关键的是,我怎么体现我要跟你建立连接?

    1. 同步位 S Y N = 1 SYN=1 SYN=1,表示在建立连接。
    2. 序号 s e q = x seq=x seq=x,指的是从序号 x x x 的字节开始发送数据。

    此时还并没有确认号、确认位的参与。

    第二次握手

    image-20220618222409118

    1. 确认号 a c k = x + 1 ack=x+1 ack=x+1,表明 x + 1 x+1 x+1 以前的序号我都收到了,下一次请你从 x + 1 x+1 x+1 开始给我发送。
    2. 既然已经有确认号了,那么确认位 A C K = 1 ACK=1 ACK=1 肯定被置为 1 1 1 了。

    此时仅代表, A A A B B B 发请求, B B B 已经收到了,但怎么确定 B B B A A A 发的数据, A A A 也能收到呢?所以还需要下面两个字段,来进行第三次的握手:

    1. S Y N = 1 SYN=1 SYN=1,代表我也向你建立连接。
    2. s e q = y seq=y seq=y,表明我从序号 y y y 开始给你发送数据。

    第一次握手表示 A A A B B B 发请求,第二次握手表示 B B B A A A 做确认,同时 B B B 也向 A A A 发起连接请求;但此时 B B B 还需要 A A A 的回应。

    就像打电话:
    A问:你能听到我说话吗?
    B回答:能,那你能听到我说话吗?
    A回答:我也能

    TCP是一个全双工的协议,所以此时必须要有第三次握手

    第三次握手

    image-20220618224418103

    A A A B B B 做出最后一次的确认,表示你刚才给我发的请求和数据我都已经收到了。

    1. 确认号 a c k = y + 1 ack=y+1 ack=y+1,表示 y + 1 y+1 y+1 之前的数据我都已经收到了。
    2. 确认位 A C K = 1 ACK=1 ACK=1
    3. 序号 s e q = x + 1 seq=x+1 seq=x+1,上次你的确认号位 x + 1 x+1 x+1,我这次就从 x + 1 x+1 x+1 开始发送数据。

    至此, A A A B B B 的连接就建立成功了。

    注意,此时同步位 S Y N = 0 SYN=0 SYN=0 已被置为 0 0 0,因为连接已经建立成功。

    三次握手TCP连接的各个状态

    • C L O S E D CLOSED CLOSED:关闭状态
    • L I S T E N LISTEN LISTEN:监听状态
    • S Y N − S E N T SYN-SENT SYNSENT:连接发送状态
    • S Y N − R C V D SYN-RCVD SYNRCVD:连接接收状态
    • E S T A B − L I S H E D ESTAB-LISHED ESTABLISHED:已确认连接状态

    image-20220618225434490

    面试题

    image-20220618210310984

    这是一道很常见的面试题,但是大家有没有思考过,为什么是 3 3 3 次呢? 2 2 2 4 4 4 次不可以吗?

    我的理解:

    • TCP是一个全双工的协议,对于发送端 A A A 和 接收端 B B B 来说,我发送的消息一定是有回复的,达到了有去有回才代表着我建立的道路是连通的,所以对于 A B AB AB 两台机器来说,都需要一去一回,这样就是 3 3 3 次了。

    • 所以 2 2 2 次握手肯定不是不够的,而对于TCP, 3 3 3 次握手就可以建立可靠连接, 4 4 4 次甚至更多次通信都会造成资源的浪费。

    更详细的图文分析可参考小林coding的TCP面试题

    从三个方面分析了三次握手的原因:

    • 三次握手才可以阻止重复历史连接的初始化(主要原因)
    • 三次握手才可以同步双方的初始序列号
    • 三次握手才可以避免资源浪费

    可以当做八股文背。

  • 相关阅读:
    java-php-python-婚纱影楼服务管理计算机毕业设计
    软件项目管理案例教程-韩万江-期末复习
    从零开始学习 Java:简单易懂的入门指南之Map集合(二十三)
    为什么很多公司都开始使用Go语言了?
    Programming Languages PartB Week2学习笔记——用Racket编写解释器
    关于YAML配置
    《C++ Primer》练习9.51:设计类解析不同的输入
    数据化运营开篇词 给你一套数据化运营的“三段式”标准路径
    python实现二叉树
    [LeetCode] 453. 最小操作次数使数组元素相等(Java)
  • 原文地址:https://blog.csdn.net/weixin_53407527/article/details/125357262