关于java:Alibaba二面面试官居然把-TCP-三次握手-问的这么细致幸好早有准备

34次阅读

共计 4915 个字符,预计需要花费 13 分钟才能阅读完成。

TCP 的三次握手和四次挥手,能够说是陈词滥调的经典问题了,通常也作为各大公司常见的面试考题,具备肯定的程度区分度。看似是简略的面试问题,如果你的答复不合乎面试官期待的水准,有可能就间接凉凉了。

本文会围绕,三次握手和四次挥手相干的一些列外围问题,分享如何更精确的答复和应答常见的面试问题,当前面对再刁钻的面试官,你都能够随便地跟他扯皮了。

面试 TCP 的意义

我想要先阐明一个重要问题,到底面试 TCP 的意义何在?

常常会听到这样埋怨:我是做业务程序开发的,面试官居然问我 TCP 三次握手、TCP 拥塞管制的问题,还问的这么粗疏?

这些同学会觉着面试官是闲的淡疼,或是成心刁难候选人,更有同学认为面试官是为了避免本人技术退化拿来练手的,这种想法我也是醉了。

当然,不同人对此可能会有不同的想法,但咱们技术人应该以踊跃的心态来了解和面对这个问题,在我看来面试 TCP 有重要的意义:

  1. 从面试官的角度,能够疾速考查候选人对基础知识的把握水平,以及候选人看待技术的那种知其所以然的态度。
  2. 从求职者的角度,即便工作内容中没有间接用到 TCP 协定,但在遇到网络故障,调试和剖析问题时,相熟 TCP 显得非常重要,要不抓包都看不懂。
  3. 从学习的角度,咱们能够学习 TCP 的设计理念,比方 TCP 重传、拥塞管制,以及如何在性能和原理之间做衡量和取舍的,触类旁通,将这些原理细节利用到咱们平时的软件设计上,也是一种思维上的学习成长。
  4. 如果想要调整 TCP 参数来晋升传输速度,可服务器上相干的零碎参数有几十个,到底该怎么调整呢?
  5. 在服务器本地的 TCP 连贯状态呈现了相似 fin_wait、time_wait,该怎么解决,是什么起因引起的?如果不懂 TCP,即便他人通知你解决方案,你也不可能真正了解的。

所以,咱们十分有必要认真学习 TCP 协定,对 TCP 相熟水平,在某种意义上也是你与他人拉开距离的重要标识。

TCP 根底

这里先帮小伙伴们相熟和回顾下 TCP 的基本概念,以至于可能更好的了解文章后边的内容。

TCP 其实是非常复杂的协定,咱们先聊一些根底的。咱们晓得 TCP 是一种牢靠的协定,它次要通过解决这几个问题来实现可靠性的,别离是:乱序、丢包重传、流控、拥塞管制。通过从图中报文格式的字段,也可能简略理解到 TCP 的相干概念。

  • TCP 在网络 OSI 七层模型中的第四层,TCP 包是没有 IP 地址的,但有源端口和目标端口,用来标识通信的过程。
  • Sequence Number 是记录包的序号,TCP 会依照报文字节进行编号,它是用来解决包在网络中乱序的问题。
  • Acknowledgement Number 确认序列号,是用于向发送方确认曾经收到了哪些包,用来解决不丢包的问题。
  • Windows 也叫 Advertised-Windows,也就是驰名的滑动窗口,次要是用来解决流控的。
  • TCP Flag 就是包的类型,次要是用于操控 TCP 状态机的。

三次握手

三次握手 是各个公司常见的面试考点。以过来人教训来讲,尽管该问题看似简略,但你还真不肯定可能答复的好。

见过比拟典型面试问答场景:

面试官 :请形容一下三次握手的过程吧
求职者 :第一次客户端给服务端发送一个报文,第二次是服务器收到包之后,也给客户端应答一个报文,第三次是客户端再给服务器发送一个回复报文,TCP 三次握手胜利。
面试官 :还有吗?
求职者 :说完了哈,这就是三次握手,很简略的
面试官:嗯,我没什么问的了,你还有什么问题吗?

这时求职者缓和的心终于平静了,因为面试官没有深刻上来的意思,持续问上来可能也不懂,大快人心!当然本次面试基本上也就 game over了。

求职者答复的不正确么?正确,然而答复的过于简略,离面试官的冀望的答案还有肯定的间隔,咱们该怎么答复呢?

TCP 三次握手,其实就是建设一个 TCP 连贯,客户端与服务器交互须要 3 个数据包。握手的次要作用就是为了确认单方的接管和发送能力是否失常,初始序列号,替换窗口大小以及 MSS 等信息。

  • 第一次握手:客户端发送 SYN 报文,并进入 SYN_SENT 状态,期待服务器的确认;
  • 第二次握手:服务器收到 SYN 报文,须要给客户端发送 ACK 确认报文,同时服务器也要向客户端发送一个 SYN 报文,所以也就是向客户端发送 SYN + ACK 报文,此时服务器进入 SYN_RCVD 状态;
  • 第三次握手:客户端收到 SYN + ACK 报文,向服务器发送确认包,客户端进入 ESTABLISHED 状态。待服务器收到客户端发送的 ACK 包也会进入 ESTABLISHED 状态,实现三次握手。

咱们答复时,能够先简略概述 TCP 过程,而后三次握手具体形容时,须要阐明状态的根本转换。

TCP 三次握手,其实就是 TCP 利用在发送数据前,通过 TCP 协定跟通信对方协商好连贯信息,建设起 TCP 的连贯关系。

咱们须要晓得,TCP 连贯并非是在通信设施两端之间建设信号隧道,而实质上就是单方各自保护所需的状态状态,以达到 TCP 连贯的成果。所以 TCP 状态机是 TCP 的核心内容,学习 TCP 肯定要搞懂这些状态机之间的转换。

二次握手能够吗

问:为什么 TCP 采纳三次握手,二次握手能够吗?

咱们能够从几个方面来解释:

(一)确认单方的收发能力

TCP 建设连贯之前,须要确认客户端与服务器单方的收包和发包的能力。

  1. 第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接管能力是失常的。
  2. 第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接管、发送能力,客户端的接管、发送能力是失常的。不过此时服务器并不能确认客户端的接管能力是否失常。
  3. 第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接管、发送能力失常,服务器本人的发送、接管能力也失常。

所以,只有三次握手能力确认单方的接管与发送能力是否失常。

(二)序列号牢靠同步

如果是两次握手,服务端无奈确定客户端是否曾经接管到了本人发送的初始序列号,如果第二次握手报文失落,那么客户端就无奈晓得服务端的初始序列号,那 TCP 的可靠性就无从谈起。

(三)阻止反复历史连贯的初始化

客户端因为某种原因发送了两个不同序号的 SYN 包,咱们晓得网络环境是简单的,旧的数据包有可能先达到服务器。如果是两次握手,服务器收到旧的 SYN 就会立即建设连贯,那么会造成网络异样。

如果是三次握手,服务器须要回复 SYN+ACK 包,客户端会比照应答的序号,如果发现是旧的报文,就会给服务器发 RST 报文,直到失常的 SYN 达到服务器后才失常建设连贯。

所以三次握手才有足够的上下文信息来判断以后连贯是否是历史连贯。

(四)平安问题

咱们晓得 TCP 新建连贯时,内核会为连贯调配一系列的内存资源,如果采纳两次握手,就建设连贯,那会放大 DDOS 攻打的。

TCP 作为一种牢靠传输控制协议,其核心思想:既要保证数据牢靠传输,又要进步传输的效率,而三次握手恰好能够满足以上两方面的需要!

初始序列号(ISN)

问:ISN 代表什么?意义何在?ISN 是固定不变的吗?ISN 为何要动态随机?

ISN 是什么?

答:ISN 全称是 Initial Sequence Number,是 TCP 发送方的字节数据编号的原点,通知对方我要开始发送数据的初始化序列号

ISN 是固定不变的吗?

答:ISN 如果是固定的,攻击者很容易猜出后续的确认序号,为了平安起见,防止被第三方猜到从而发送伪造的 RST 报文,因而 ISN 是动静生成的

半连贯队列

什么是半连贯队列?

答:服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时单方还没有齐全建设连贯。服务器会把这种状态下申请连贯放在一个队列里,咱们把这种队列称之为半连贯队列。

当然还有一个全连贯队列,就是曾经实现三次握手,建设起连贯的就会放在全连贯队列中。如果队列满了就有可能会呈现丢包景象。

三次握手能够携带数据吗?

问:三次握手过程中,能够携带数据吗?

答:第一次、第二次握手不能够携带数据,而第三次握手是能够携带数据的。

咱们能够思考一个问题,如果第一次握手能够携带数据的话,如果有人要歹意攻打服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据,疯狂着重复发 SYN 报文,这会让服务器破费大量的内存空间来缓存这些报文,这样服务器就更容易被攻打了。

对于第三次握手,此时客户端曾经处于连贯状态,他曾经晓得服务器的接管、发送能力是失常的了,所以能够携带数据是情理之中。

TCP 四次挥手

当咱们的应用程序不须要数据通信了,就会发动断开 TCP 连贯。建设一个连贯须要三次握手,而终止一个连贯须要通过四次挥手。

  • 第一次挥手。客户端发动 FIN 包(FIN = 1), 客户端进入 FIN_WAIT_1 状态。TCP 规定,即便 FIN 包不携带数据,也要耗费一个序号。
  • 第二次挥手。服务器端收到 FIN 包,收回确认包 ACK(ack = u + 1),并带上本人的序号 seq=v,服务器端进入了 CLOSE_WAIT 状态。这个时候客户端曾经没有数据要发送了,不过服务器端有数据发送的话,客户端仍然须要接管。客户端接管到服务器端发送的 ACK 后,进入了 FIN_WAIT_2 状态。
  • 第三次挥手。服务器端数据发送结束后,向客户端发送 FIN 包(seq=w ack=u+1),半连贯状态下服务器可能又发送了一些数据,假如发送 seq 为 w。服务器此时进入了 LAST_ACK 状态。
  • 第四次挥手。客户端收到服务器的 FIN 包后,收回确认包(ACK=1,ack=w+1),此时客户端就进入了 TIME_WAIT 状态。留神此时 TCP 连贯还没有开释,必须通过 2*MSL 后,才进入 CLOSED 状态。而服务器端收到客户端的确认包 ACK 后就进入了 CLOSED 状态,能够看出服务器端完结 TCP 连贯的工夫要比客户端早一些。

问:为什么建设连贯握手三次,敞开连贯时须要是四次呢?

答:其实在 TCP 握手的时候,接收端发送 SYN+ACK 的包是将一个 ACK 和一个 SYN 合并到一个包中,所以缩小了一次包的发送,三次实现握手。

对于四次挥手,因为 TCP 是全双工通信,在被动敞开方发送 FIN 包后,接收端可能还要发送数据,不能立刻敞开服务器端到客户端的数据通道,所以也就不能将服务器端的 FIN 包与对客户端的 ACK 包合并发送,只能先确认 ACK,而后服务器待无需发送数据时再发送 FIN 包,所以四次挥手时必须是四次数据包的交互。

问:为什么 TIME_WAIT 状态须要通过 2MSL 能力返回到 CLOSE 状态?

答:MSL 指的是报文在网络中最大生存工夫。在客户端发送对服务器端的 FIN 的确认包 ACK 后,这个 ACK 包是有可能不可达的,服务器端如果收不到 ACK 的话须要从新发送 FIN 包。

所以客户端发送 ACK 后须要留出 2MSL 工夫(ACK 达到服务器 + 服务器发送 FIN 重传包,一来一回)期待确认服务器端的确收到了 ACK 包。

也就是说客户端如果期待 2MSL 工夫也没有收到服务器端的重传包 FIN,阐明能够确认服务器曾经收到客户端发送的 ACK

还有第 2 个理由,防止新旧连贯混同。

在客户端发送完最初一个 ACK 报文段后,在通过 2MSL 工夫,就能够使本连贯继续的工夫内所产生的所有报文都从网络中隐没,使下一个新的连贯中不会呈现这种旧的连贯申请报文。

你要晓得,有些自作主张的路由器会缓存 IP 数据包,如果连贯重用了,那么这些提早收到的包就有可能会跟新连贯混在一起。

集体整顿了一些材料,有须要的敌人能够间接点击支付。

25 大 Java 面试专题(附解析)

从 0 到 1Java 学习路线和材料

Java 外围常识集

MySQL 王者升级之路

总结

本篇文章以 TCP 三次握手和四次挥手这个经典问题为主题,初步窥探了 TCP 协定的入门知识点,后边会有一系列的文章,来分享 TCP 协定相干的方方面面,如果感兴趣请关注我,咱们一起把 TCP 协定彻底搞透彻了。

最初,帮大家总结一下 TCP 的外围知识点。咱们晓得 TCP 协定是牢靠的,它次要是通过解决如下几个问题来保障可靠性的:

  • 乱序
  • 丢包
  • 流控
  • 拥塞管制

TCP 是一个巨简单的协定,基本上 TCP 波及的所有内容都是围绕解决这几个问题的,请务必时刻认真牢记。

正文完
 0