徐锦洪 发表于 2022-6-26 13:47:14

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

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

TCP报文段首部

大致的流程想必大家并不陌生,我们先具体分析一下它这三次传输 首部都包含了哪些信息。
我们先来认识一下TCP报文段的首部都有哪些字段是需要用到的:


[*]                                       s                            e                            q                                  seq                     seq:序号
➢ TCP会给每一个字节都编上一个序号,而序号字段的值则是当前报文段所发送数据报的第一个字节的序号。
➢ 假设当前发送的数据序号为                                       1                            −                            200                                  1-200                     1−200,那么序号字段的值就是                                       1                                  1                     1。
https://img-blog.csdnimg.cn/img_convert/ac7be3eb749c392bcd137eaedf2eb95a.png#pic_center


[*]                                       a                            c                            k                                  ack                     ack:确认号
➢ 确认号的值是期望收到对方下一个报文段的数据的第一个字节的序号
➢ 假设上方举例 发送的数据序号为                                       1                            −                            200                                  1-200                     1−200:发送方为                                       A                                  A                     A,接收方为                                       B                                  B                     B,那么此时                                       B                                  B                     B 返回的确认号即为                                       201                                  201                     201。
https://img-blog.csdnimg.cn/img_convert/92d03fccd68a2dbc9f8829152ce27fd5.png#pic_center
一共需要用到两个校验位                               (                      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 时,连接建立成功。
https://img-blog.csdnimg.cn/img_convert/ad7958cfcd2bd98e4e2172adacc83713.png#pic_center


[*]                                       A                            C                            K                                  ACK                     ACK:确认位
➢ 当确认位被置为                                       1                                  1                     1 时,说明确认号字段有效。
➢ 当确认位被置为                                       0                                  0                     0 时,确认号无效。
https://img-blog.csdnimg.cn/img_convert/6c0f22fedc513613ebd3339c1cc2f1de.png#pic_center
   注意:确认号                                       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)。
第一次握手

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

[*]同步位                                    S                         Y                         N                         =                         1                              SYN=1                  SYN=1,表示在建立连接。
[*]序号                                    s                         e                         q                         =                         x                              seq=x                  seq=x,指的是从序号                                    x                              x                  x 的字节开始发送数据。
此时还并没有确认号、确认位的参与。
第二次握手

https://img-blog.csdnimg.cn/img_convert/ed7395851fcc9684fdfa0cdfc5227890.png#pic_center

[*]确认号                                    a                         c                         k                         =                         x                         +                         1                              ack=x+1                  ack=x+1,表明                                    x                         +                         1                              x+1                  x+1 以前的序号我都收到了,下一次请你从                                    x                         +                         1                              x+1                  x+1 开始给我发送。
[*]既然已经有确认号了,那么确认位                                    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 也能收到呢?所以还需要下面两个字段,来进行第三次的握手:

[*]                                 S                         Y                         N                         =                         1                              SYN=1                  SYN=1,代表我也向你建立连接。
[*]                                 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是一个全双工的协议,所以此时必须要有第三次握手。
第三次握手

https://img-blog.csdnimg.cn/img_convert/07c6537b5c74621b57264fc1d3efd9f9.png#pic_center
                               A                        A               A 给                               B                        B               B 做出最后一次的确认,表示你刚才给我发的请求和数据我都已经收到了。

[*]确认号                                    a                         c                         k                         =                         y                         +                         1                              ack=y+1                  ack=y+1,表示                                    y                         +                         1                              y+1                  y+1 之前的数据我都已经收到了。
[*]确认位                                    A                         C                         K                         =                         1                              ACK=1                  ACK=1
[*]序号                                    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                  SYN−SENT:连接发送状态
[*]                                 S                         Y                         N                         −                         R                         C                         V                         D                              SYN-RCVD                  SYN−RCVD:连接接收状态
[*]                                 E                         S                         T                         A                         B                         −                         L                         I                         S                         H                         E                         D                              ESTAB-LISHED                  ESTAB−LISHED:已确认连接状态
https://img-blog.csdnimg.cn/img_convert/2a4c133136194df2c1401d49ef8b9202.png#pic_center
面试题

https://img-blog.csdnimg.cn/img_convert/5bc7ceaf9aa8ffa3b7228ec8d62798b8.png#pic_center
这是一道很常见的面试题,但是大家有没有思考过,为什么是                                    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面试题
从三个方面分析了三次握手的原因:


[*]三次握手才可以阻止重复历史连接的初始化(主要原因)
[*]三次握手才可以同步双方的初始序列号
[*]三次握手才可以避免资源浪费
可以当做八股文背。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 【计算机网络】TCP为什么需要3次握手