面试官问我TCP三次握手和四次挥手,我真的是

候选者面试官你好,请问面试可以开始了吗

面试官:嗯,开始吧

面试官今天来聊聊TCP吧,TCP的各个状态还有印象吗?

候选者:还有些许印象的,要不我就来简单说下TCP的三次握手和四次挥手的流程吧

候选者:说完这两个流程,就能把TCP的状态给涵盖上了

面试官:可以吧

候选者:在说TCP的三次握手和四次挥手之前,我先给你画下TCP的头部格式呗(:

面试官问我TCP三次握手和四次挥手,我真的是

候选者:对于TCP三次握手和四次挥手,我们最主要的就是关注TCP头部的序列号、确认号以及几个标记位(SYN/FIN/ACK/RST)

候选者:序列号:在初次建立连接的时候,客户端和服务端都会为「本次的连接」随机初始化一个序列号。(纵观整个TCP流程中,序列号可以用来解决网络包乱序的问题)

候选者:确认号:该字段表示「接收端」告诉「发送端」对上一个数据包已经成功接收(确认号可以⽤来解决网络包丢失的问题)

候选者:而标记位就很好理解啦。SYN为1时,表示希望创建连接。ACK为1时,确认号字段有效。FIN为1时,表示希望断开连接。RST为1时,表示TCP连接出现异常,需要断开。

面试官问我TCP三次握手和四次挥手,我真的是

候选者:下面就先从三次握手开始吧,期间我也会在三次握手中涉及到的TCP状态也说下的。

候选者:TCP三次握手的过程其实就是在:确认通信双方(客户端和服务端)的序列号

面试官问我TCP三次握手和四次挥手,我真的是

候选者:它的过程是这样的

候选者:在最开始的时候,客户端和服务端都处于 CLOSE 状态

候选者:服务器主动监听某个端口,处于 LISTEN 状态

候选者:客户端会随机生成出序列号(这里的序列号一般叫做client_isn),并且把标志位设置为SYN(意味着要连接),然后把该报文发送给服务端

候选者:客户端发送完SYN报文以后,自己便进入了 SYN_SEND 状态

面试官问我TCP三次握手和四次挥手,我真的是

候选者:服务端接收到了客户端的请求之后,自己也初始化对应的序列号(这里的序列号一般叫做 server_isn)

候选者:在「确认号」字段里填上client_isn + 1(相当于告诉客户端,已经收到了发送过来的序列号了) ,并且把 SYN 和 ACK 标记位都点亮(置为1)

候选者:把该报文发送客户端,服务端的状态变成 SYN-REVD 状态

面试官问我TCP三次握手和四次挥手,我真的是

候选者:客户端收到服务端发送的报文后,就知道服务端已经接收到了自己的序列号(通过确认号就可以知道),并且接收到了服务端的序列号(server_isn)

候选者:此时,客户端需要告诉服务端自己已经接收到了他发送过来的序列号,所以在「确认号」字段上填上server_isn+1,,并且标记位 ACK 为1

面试官问我TCP三次握手和四次挥手,我真的是

候选者:客户端在发送报文之后,进入 ESTABLISHED 状态,而服务端接收到客户端的报文之后,也进入 ESTABLISHED 状态

候选者:这就是三次握手的过程以及涉及到的TCP状态

候选者:总结下来,就是双方都把自身的序列号发给对方,看对方能不能接收到。如果「确认可以」,那就可以正常通信。(三次握手这个过程就可以看到双方都有接收和发送的能力)

面试官那两次握手行吗?

候选者:两次握手只能保证客户端的序列号成功被服务端接收,而服务端是无法确认自己的序列号是否被客户端成功接收。所以是不行的(:

面试官了解了,那我想问问序列号为什么是随机的?以及序列号是怎么生成的?

候选者:一方面为了安全性(随机ISN能避免非同一网络的攻击),另一方面可以让通信双方能够根据序号将「不属于」本连接的报文段丢弃

候选者:序列号怎么生成的?这…随便猜下就应该跟「时钟」和TCP头部的某些属性做运算生成的吧,类似于雪花算法(:具体我忘了。

面试官既然网络是不可靠的,那建立连接不是会经过三次握手吗?那要是在中途丢了,怎么办?

候选者:假设第一个包丢了,客户端发送给服务端的 SYN 包丢了(简而要之就是服务端没接收到客户端的SYN包)

候选者:客户端迟迟收不到服务端的ACK包,那会周期性超时重传,直到收到服务端的ACK

候选者:假设第二个包丢了,服务端发送的SYN+ACK包丢了(简而要之就是客户端没接收到服务端的SYN+ACK包)

候选者:服务端迟迟收不到客户端的ACK包,那会周期性超时重传,直到收到客户端的ACK

候选者:假设第三个包丢了(ACK包),客户端发送完第三个包后单方面进入了 ESTABLISHED 状态,而服务端也认为此时连接是正常的,但第三个包没到达服务端

候选者:一、如果此时客户端与服务端都还没数据发送,那服务端会认为自己发送的SYN+ACK的包没发送至客户端,所以会超时重传自己的SYN+ACK包

候选者:二、如果这时候客户端已经要发送数据了,服务端接收到了ACK + Data数据包,那自然就切换到 ESTABLISHED 状态下,并且接收客户端的Data数据包

候选者:三、如果此时服务端要发送数据了,但发送不了,会一直周期性超时重传SYN + ACK,直到接收到客户端的ACK包

面试官问我TCP三次握手和四次挥手,我真的是

面试官嗯,是不是要讲下四次挥手了?

候选者:嗯,在建立完连接之后,客户端和服务端双方都处于 ESTABLISHED 状态状态

候选者:断开连接双方都有权利的,下面我还是以客户端主动断开为例好啦。

候选者:客户端打算关闭连接,会发 FIN 报文给服务端(其实就是把标志位 FIN 点亮),客户端发送完之后,就进入FIN_WAIT_1状态

候选者:服务端收到 FIN 报文之后,回复 ACK 报文给客户端(表示已经收到了),服务端发送完之后,就进入 CLOSE_WAIT 状态

候选者:客户端接收到服务端的 ACK 报文,就进入了 FIN_WAIT_2 状态

面试官问我TCP三次握手和四次挥手,我真的是

候选者:这时候,服务器可能还有数据要发送给客户端,等服务端确认自己已经没有数据返回给客户端之后,就发送FIN报文给客户端了,自己进入 LAST_ACK 状态

候选者:客户端收到服务端的FIN报文之后,回应ACK报文,自己进入 TIME_WAIT 状态

候选者:服务端收到客户端的ACK报文之后,服务端就进入 CLOSE 状态

候选者:客户端在TIME_WAIT等到2MSL,也进入了 CLOSE 状态

面试官问我TCP三次握手和四次挥手,我真的是

候选者:四次挥手的流程到这里就结束了,结合三次握手,TCP的各个状态也已经说完了。

面试官:嗯嗯,刚聊完四次挥手嘛,那你觉得为什么是四次呢?

候选者:其实很好理解,当客户端第一次发送 FIN 报文之后,只是代表着客户端不再发送数据给服务端,但此时客户端还是有接收数据的能力的。而服务端收到FIN报文的时候,可能还有数据要传输给客户端,所以只能先回复 ACK给客户端

候选者:等到服务端不再有数据发送给客户端时,才发送 FIN 报文给客户端,表示可以关闭了。

候选者:所以,一来一回就四次了。

面试官问我TCP三次握手和四次挥手,我真的是

面试官从四次挥手的流程上来看,有个 TIME_WAIT 状态,你知道这个状态干什么用的吗?(等待 2MSL)

候选者:主要有两个原因吧。1.保证最后的 ACK 报文 「接收方」一定能收到(如果收不到,对方会 重发 FIN 报文)2. 确保在创建新连接时,先前网络中残余的数据都丢失了

候选者:其实也比较好理解的。就正如我们重启服务器一样,会先优雅关闭各种资源,再留有一段时间,希望在这段时间内,资源是正常关闭的,这样重启服务器(或者发布)就基本认为不会影响到线上运行了。

面试官假设 TIME_WAIT 状态多过会有什么危害?怎么解决呢?

候选者:从流程上看, TIME_WAIT 状态 只会出现在 主动发起 关闭连接的一方。危害就是会占用内存资源和端口呗(毕竟在等待嘛),解决的话,有Linux参数可以设置,具体忘了额。

面试官:今天最后再问个问题吧, 我们常说TCP连接,那这个连接到底是什么?你是怎么理解的?

候选者:其实从三次握手可以发现的是,TCP建立连接无非就是交换了双方的状态(比如序列号)。然后就没有然后了…连接本质上「只是互相维持一个状态,有连接特性」

面试官:好吧。

面试官问我TCP三次握手和四次挥手,我真的是

欢迎关注我的微信公众号【 Java3y】来聊聊Java面试,对线面试官系列持续更新中!

面试官问我TCP三次握手和四次挥手,我真的是

【对线面试官+从零编写Java项目】 持续高强度更新中!求star

原创不易!!求三连!!

Original: https://www.cnblogs.com/Java3y/p/15725895.html
Author: Java3y
Title: 面试官问我TCP三次握手和四次挥手,我真的是

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/594464/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Redis的订阅和发布

    发布与订阅模型,放在每一位开发者身上,都是耳熟能详的一对词语。与设计模式里面的–观察者模式非常相似。在微服务中,把消息中介分离出来成为独立服务,无论是跨服务通信开发和运…

    Java 2023年6月14日
    0103
  • 引用拷贝,浅拷贝和深拷贝

    1.引用拷贝 引用拷贝会生成一个新的对象引用地址,但是两个最终指向依然是同一个对象。 class Son { String name; int age; public Son(St…

    Java 2023年6月5日
    061
  • springBoot使用注解Aop实现日志模块

    我们在日常业务操作中需要记录很多日志,可以在我们需要的方法中对日志进行保存操作,但是对业务代码入侵性大。使用切面针对控制类进行处理灵活度不高,因此我们可以使用自定义注解来针对方法进…

    Java 2023年6月8日
    088
  • 哈工大软件构造Lab3(2022)

    (防扒小助手) 本人CSDN博客: https://blog.csdn.net/m0_61753302 ; 本人博客园博客(同步CSDN): 何以牵尘 – 博客园 (c…

    Java 2023年6月9日
    061
  • VBA爬虫案例

    Private Sub 批量获取()Dim rowTotal!, res$, i!, t!, index! Dim objXML, objSC, obj, strModel$, q…

    Java 2023年6月16日
    047
  • (转)Math.Round() — c# 与 java的区别

    明明知道,java与c#在很多方面都有很多不同,但是如果让详细描述,却不一定能说出来多少。 前段时间碰见一个问题,才恍然大悟般的,明白了一条不同。 有同事的同学笔试,有道题目是 M…

    Java 2023年5月29日
    084
  • 2020年10月23日笔记

    Java8特性待更新 在公司项目里面有很多这类代码,熟练使用后能够加快开发速度。1、快速便利map的方法map进行快速遍历的方法map.forEach((key,value)-&g…

    Java 2023年6月13日
    059
  • 每日一练

    2022/6/2 这种情况肯定不能修改 final int a=1; a=2; 那么引用类型呢? final int[] arr={1,2,3,4}; arr[1]=100; 可以…

    Java 2023年6月13日
    080
  • 如何利用 RPA 实现自动化获客?

    大家好,我是二哥。前高级技术专家 & 增长黑客,现一枚爱折腾的小小创业者,专注于 RPA & SaaS 软件这块。这次给大家带来如何利用 RPA 实现自动化获客 一…

    Java 2023年6月13日
    074
  • axios二次封装

    查看代码 import axiox from ‘axios’ import store from "@/store"; import utils from &q…

    Java 2023年6月8日
    085
  • Try-with-resources are not supported at language level ‘5’

    Try-with-resources are not supported at language level ‘5’没有指定maven版本导致 的 指定ma…

    Java 2023年6月15日
    096
  • eShopOnContainers 是一个基于微服务的.NET Core示例框架

    找到一个好的示例框架很难,但不是不可能。大多数是小型Todo风格的应用程序,通常基于SimpleCRUD。值得庆幸的是,Microsoft已经为eShopOnContainers创…

    Java 2023年6月7日
    067
  • Elasticsearch和Solr的区别

    1、基于Lucene开发 java;gutter:true; 他们底层都是基于Lucene开发,使用了Lucene的倒排索引实现的</p> <pre>&lt…

    Java 2023年6月13日
    065
  • 基本运算符

    运算符 JAVA语言支持入下运算符。 %:余数 !=:不等于 &&:and ||:or !:not 二元运算符 整数默认为int类型,按类型优先级自动转换,下图说明…

    Java 2023年6月9日
    077
  • 分析自动打卡脚本——大一入学遗作

    HTTP协议 1.何为HTTP协议 HTTP协议又名超文本传输协议,是一种基于TCP/IP的传输协议,顾名思义,其传输的内容为超文本内容,在互联网早期,我们只能传输非二进制的文本,…

    Java 2023年6月7日
    087
  • 【Java面试】当任务数超过线程池的核心线程数时,如何让它不进入队列,而是直接启用最大线程数

    你们知道,”当任务数超过线程池的核心线程数时,如何让它不进入队列,而是直接启用最大线程数”吗?大家好,我是Mic,一个工作了14年的Java程序员。刚刚这个…

    Java 2023年6月16日
    069
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球