再有面试官问TCP三次握手,你就拿这篇文章糊他脸(轻松幽默带你理解TCP的通信原理:深度好文)

面试情景

一天,你进入了一个大厂面试。坐立不安之中,一个秃头中年男子,穿着一个发灰了的格子衬衫,戴着一副镜片厚9mm的眼镜,稳如磐石突然朝着你说到:“就是你这个小毛头来面试吧。”

心里一惊,这怕不是神仙级架构师。但还是故作镇定:“面试官您好,我是xxx…”

面试过程中……面试官随手抛来一句:“简单说说 TCP 三次握手吧。”。

简单说说???嗯,面试官人还不错。
再加上我面试前的精心准备,和饱读诗书的才华,和挥斥方遒的潇洒帅气,一定能深深折服他。
于是:“ TCP 三次握手很简单,

  1. 客户端首先生成一个 SYN 报文,随机生成一个 seq,发给服务端。
  2. 服务端生成一个 SYN 报文,随机生成一个 seq,返回一个 ACK(为客户端的 seq + 1),发给客户端。
  3. 客户端再返回一个ACK(为服务端的 seq + 1)和 seq(为先前的 seq + 1,也是服务端返回的 ACK 的值)。

三次握手就完成了。”

面试官再问:

  1. SYN 是啥
  2. seq 是啥
  3. ACK 是啥
  4. 为啥返回的 ACK = seq + 1
  5. TCP 3 次握手可以携带数据吗
  6. 为啥一定要 “3” 次,2 次不行吗
  7. 为啥断开要 4 次,不能 3 次吗
  8. 如果报文段丢失怎么办
  9. 报文超长延迟怎么办
  10. 网络拥塞怎么办

这都啥?????
“你回去等通知吧。”

<瑟瑟发抖>

下面进入正题,如果上面的题你都理解,能够熟练回答,那对于 TCP 原理你了解得已经比较透彻了。
背三次握手的过程可能很简单,但是面试官细问,那你就露馅了,所以得深入理解才行。
要了解 TCP 的三次握手,你首先需要了解 TCP 的通信原理。
(以下所有图片摘自《计算机网络 自顶向下方法》)

我们先看 TCP 报文段结构(不用全部都理解)
我们只需要关注到,其中有

  • 首部(只需要知道有这个东西)
  • 序号字段 (32比特)
  • 确认号字段 (序号和确认号用来实现:传输可靠)(32比特)

下面进行深入解释
图片摘自
为了实现通信的可靠,就需要一方对另一方的发送的数据进行:回复确认。

扫描二维码关注公众号,回复: 9828316 查看本文章
  • 比如:
  • A 对 B 说,我要去你家啦。
    (这时 A 还不知道 B 有没有收到 A 要过去的消息,所以他不能随意去别人家)
  • (直到)B 对 A 说,好的,请来吧。
    (这时 B 就可以确认 A 已经收到了消息,他就可以放心的过去了)

这就是 TCP 来实现通讯可靠的原理。
在 TCP 通讯中。

  • 举个例子
  • A 发送了一条数据报文,Seq = 100,data 长度为 20
  • B 接收成功,返回的 ACK = 120。
    (返回的 ACK = 发送的 Seq + data 长度)
  • 如果 A 要再次发送,则 Seq = 120。
    (根据收到的 ACK = 120 可得知数据发送序号已经到 120 了,便可以接着发送)

这里返回的 ACK = 发送的 Seq + data 的长度。(用来表示全部收到)
在 TCP 中,两边都是有 Seq 和 ACK 和各自的 data 的。

  • 以《计算机网络 自顶向下方法》书中的例子来说明
  • A 和 B 都发送了一个一个字符 ‘ C ’ 给对方(也就是长度为 1 )
  • A 发送 Seq = 42,ACK = 79,data = ‘ C ’
  • B 接收了成功之后,返回给 B 的 ACK = 43,data = ‘ C ’ 自己的 Seq = 79
    (因为 A 返回给他的 ACK = 79,说明 B 之前的发送序号已经达到到了 79,所以 Seq = 79)
  • A 此时没有数据要发送,所以返回时,只需要设置 ACK = 80,Seq = 43。
    (返回时可以不带数据,ACK 用来确认,Seq 只是必须包含在内而已)
    在这里插入图片描述
    再举个例子
  • A 发送了三条报文给 B
  • Seq = 92,数据有 8 个字节
  • 那第二条 Seq 一定 = 100,此时数据有 20 个字节
  • 第三条 Seq = 120,数据有 30 个字节
  • A 等待 B 返回的 ACK
  • B 返回一条 ACK = 100,一条 ACK = 120,一条 ACK = 150
  • 此时,正常情况下会收到三条 ACK 的返回。
    不过 A 只需要收到一条 ACK = 150 即可
    (ACK = 150 表示所有的数据都已经收到)
  • 可能网络各种原因,导致丢失报文。
    比如 ACK = 100,ACK = 120, 丢失。但是 ACK = 150 收到,则可以确认数据全部传输成功。
    若只收到 ACK = 120,则表示前两条数据传输成功,第三条报文出现问题。

现在,我们便已经明白了 TCP 传输的原理。
而 TCP 建立连接的过程,仅仅是发送特殊的报文来表示而已。
所以很容易可以明白。

TCP 三次握手过程

简单的说就是:

  1. 客户端向服务端发起连接请求
  2. 服务端回复确认
  3. 服务端向客户端发起连接请求
  4. 客户端回复确认

乍一看好像有 4 步,实际上,2、3两步可以成为一步。
服务端回复消息的时候,可以既确认客户端的请求,也发起自己的请求。
所以就是三次握手了

但跟面试官不能只说得这么扯皮,下面说得严谨一些

  1. 客户端 先向 服务端 发送一条特殊的报文段
    其中不包含应用层数据
    !在报文段首部中的一个标志位(即 SYN 比特)被置为 1(SYN = 1)
    Seq = 随机选择一个初始序号 client_isn
  2. 服务端 从收到的报文中提取出 SYN 比特位,发现这是一条请求连接的报文
    于是为该 TCP 连接分配缓存和变量
    返回给 客户端 的报文也不能包含应用层数据
    报文的 SYN 比特也设置为 1(SYN = 1)
    ACK = client_isn + 1(也就是 C 发来的 Seq + 1)
    Seq = server_isn(服务器自己的初始序号)
  3. 客户端 收到 服务端 发来的报文
    给该链接分配缓存变量
    返回报文给服务器表示确认,ACK = server_isn + 1。
    SYN = 0,表示连接成功(以后的 SYN 都为 0)
    这时的报文已经可以包含应用层数据了

在这里插入图片描述

四次挥手

同理,要理解四次挥手也很简单。

  1. 客户端向服务端发起分手请求
  2. 服务端回复确认
  3. 服务端向客户端发起分手请求
  4. 客户端回复确认

???
为啥 2、3 不能放在一块做 3 次 “分手”呢
实际上也是可以的。
只是因为一般来说,服务端在回复确认了中断连接的报文之后,很可能还有数据没有发送完。只有等到要发送给 “ 心爱的ta ” 的数据都发送完了之后,才会发送 “ 分手 ” 请求。
所以,先给对方回一个确认,然后过一会发送完数据,再发送中断连接报文。
中断报文则是 FIN 报文。如图:
在这里插入图片描述
现在我已经理解了 TCP 的通讯原理了。
但是还有问题没有解决。
比如:

  • 如果 A 给 B 发了报文,但是 B 一直没收到?
  • 或者 A 给 B 发了多个报文,但 B 只收到一部分?
  • 或者 A 给 B 发了报文,隔了很久很久 B 才收到?
  • 或者 A 给 B 发了报文,B 的回信丢失了?

那就需要重新发送,规则是
根据发送时间,计算是否超时
根据 B 返回的 ACK 判断,ACK 为多少,则代表 B 确认了多少,A 就要让 Seq = ACK,重新发送从该位置起,之后的数据

假设 A 给 B 发送了报文,Seq = 92,包含 8 个字节数据
那么 A 需要 B 返回的 ACK = 100 来确认
假设 B 的确认报文丢失了,或者传输时间过长。
那么 A 等了半天一直没有收到确认,则会将消息重新发送。
B 收到第二条一样的报文,知道了 A 没有得到确认,则会再次返回 ACK 来确认
在这里插入图片描述
假设 A 发送了两个报文
Seq = 92,8 个字节
Seq = 100,20 个字节
那么 A 就在等待 ACK = 100 和 ACK = 120 的报文。
可是 A 等了半天没反应,准备重发。
A 发送 Seq = 92,8 个字节
然后 A 就收到了 ACK = 100 和 ACK = 120
这时,第二条报文就不用再重发,已经保证了数据全部传输成功
而 B 收到重发的请求,虽然是第一条,但是仍需要发 ACK = 120 告知全部完成
(感觉还是看图最清楚,语言解释反而麻烦)
在这里插入图片描述
假设 A 发送的两段报文
Seq = 92,8 个字节
Seq = 100,20 个字节
那么 A 就在等待 ACK = 100 和 ACK = 120 的报文。
但是 ACK = 100 的报文丢失
不过 ACK = 120 到达则代表了 120 以前的全部成功(所以 ACK = 100 丢了无所谓)
在这里插入图片描述

发布了9 篇原创文章 · 获赞 123 · 访问量 4550

猜你喜欢

转载自blog.csdn.net/weixin_44051223/article/details/104210845