IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> b站前端老猫总结面试题 -> 正文阅读

[JavaScript知识库]b站前端老猫总结面试题

在浏览器中输入URL并回车后都发生了什么?

一、解析URL

URL(Universal Resource Locator):统一资源定位符。俗称网页地址或者网址。
URL用来表示某个资源的地址。(通过俗称就能看出来)

URL主要由以下几个部分组成:

· a.传输协议

· b.服务器

· c.域名

· d.端口

· e.虚拟目录

· f.文件名

· g.锚

· h.参数

现在来讨论URL解析,当在浏览器中输入URL后,浏览器首先对拿到的URL进行识别,抽取出域名字段。

二、DNS解析

DNS解析(域名解析),DNS实际上是一个域名和IP对应的数据库。

IP地址往都难以记住,但机器间互相只认IP地址,于是人们发明了域名,让域名与IP地址之间一一对应,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,整个过程是自动进行的。

可以在浏览器中输入IP地址浏览网站,也可以输入域名查询网站,虽然得出的内容是一样的,但是调用的过程不一样,输入IP地址是直接从主机上调用内容,输入域名是通过域名解析服务器指向对应的主机的IP地址,再从主机调用网站的内容。

在进行DNS解析时,会经历以下步骤:

1. 查询浏览器缓存(浏览器会缓存之前拿到的DNS 2-30分钟时间),如果没有找到,那么->

2. 检查系统缓存,检查hosts文件,这个文件保存了一些以前访问过的网站的域名和IP的数据。它就像是一个本地的数据库。如果找到就可以直接获取目标主机的IP地址了。没有找到的话,那么->

3. 检查路由器缓存,路由器有自己的DNS缓存,可能就包括了这在查询的内容;如果没有,那么->

4. **查询ISP DNS 缓存:**ISP服务商DNS缓存(本地服务器缓存)那里可能有相关的内容,如果还不行的话,那么->

5. 递归查询:从根域名服务器到顶级域名服务器再到极限域名服务器依次搜索对应目标域名的IP。

通过以上的查找,就可以获取到域名对应的IP了。接下来就是向该IP地址定位的HTTP服务器发起TCP连接。

三、浏览器与网站建立TCP连接(三次握手)

第一次握手:客户端向服务器端发送请求(SYN=1) 等待服务器确认;

第二次握手:服务器收到请求并确认,回复一个指令(SYN=1,ACK=1);

第三次握手:客户端收到服务器的回复指令并返回确认(ACK=1)。

通过三次握手,建立了客户端和服务器之间的连接,现在可以请求和传输数据了。

四、请求和传输数据

比如要通过get请求访问“http://www.dydh.org/”,通过抓包可以看到:

请求网址(url):http://www.dydh.org/
请求方法:GET
远程地址:IP
状态码:200 OK
Http版本: HTTP/1.1
请求头: …
响应头: …

响应头中有一个:Set-Cookie:“PHPSESSID=c882giens9f7d3oglcakhrl994; path=/”,说明浏览器中没有关于这个网站的cookie信息。

当我们下一次访问相同的网站时:

可以看到,请求头中包含了这个cookie信息,

Cookie:"PHPSESSID=c882giens9f7d3oglcakhrl994; CNZZDATA1253283365=1870471808-1473694656-%7C1473694656"

cookie可以用来保存一些有用的信息:Cookies如果是首次访问,会提示服务器建立用户缓存信息,如果不是,可以利用Cookies对应键值,找到相应缓存,缓存里面存放着用户名,密码和一些用户设置项。

通过这种GET请求,和服务器的响应。可以将服务器上的目标文件传输到浏览器进行渲染。

五、浏览器渲染页面

客户端拿到服务器端传输来的文件,找到HTML和MIME文件,通过MIME文件,浏览器知道要用页面渲染引擎来处理HTML文件。

1. 浏览器会解析html源码,然后创建一个 DOM树。

在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文本节点。

2. 浏览器解析CSS代码,计算出最终的样式数据,形成css对象模型CSSOM。

首先会忽略非法的CSS代码,之后按照浏览器默认设置——用户设置——外链样式——内联样式——HTML中的style样式顺序进行渲染。

3. 利用DOM和CSSOM构建一个渲染树(rendering tree)。
渲染树和DOM树有点像,但是是有区别的。

DOM树完全和html标签一一对应,但是渲染树会忽略掉不需要渲染的元素,比如head、display:none的元素等。

而且一大段文本中的每一个行在渲染树中都是独立的一个节点。
渲染树中的每一个节点都存储有对应的css属性。

4. 浏览器就根据渲染树直接把页面绘制到屏幕上。


你是如何理解html语义化标签的?

  1. 语义化标签的出现不是为了方便我们用户去阅读,而是方便我们的机器去阅读我们的代码,在没有样式的前提下,语义化标签同样会呈现出一个清晰的结构。

  2. 爬虫搜索,搜索引擎的爬虫是靠语义化标签内部的关键字确定它的上下文和权重,在写代码时适当的去使用,那么就会加大我们整个页面的权重,能够让我们的页面的排名在搜索引擎上的名词更靠前。

  3. 语义化标签极大提高了我们代码的可读性,在我们协同化开发的过程中,那么我们开发人员之间就可以很清晰的看懂互相的解构,然后提高我们的开发效率。

闭包

闭包是有权访问其他函数的局部变量的一个函数。

  1. 为什么其他不是闭包的函数不能访问另外函数内的作用域?为什么闭包有这个权限?

由于在js中,变量的作用域属于函数作用域,在函数执行后,作用域就会被清理、内存说也随之被收回,但是由于闭包是建立在另一个函数内部的子函数,由于其可访问上级作用域的原因,即使上级函数执行完,作用域也不会随之销毁,这是的子函数就是闭包,也就拥有了访问上级作用域中的变量的权限,即使上级函数执行完后,作用域的值也不会被销毁。

闭包的作用?

  1. 可以读取函数内部的变量
  2. 可以让这些变量的值始终保存在内存中

闭包有哪些应用场景?

闭包随处可见,一个ajax的请求的成功回调,一个事件绑定的回调方法,一个setTimeout的延时回调,或者一个函数内部返回另一个匿名函数,这些都是闭包。简而言之,无论使用何种方式对函数类型的值进行传递,当函数在别处被调用时都有闭包的影子。

闭包的注意点?

由于闭包会使得函数中的变量都保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在ie中可能导致内存泄漏,解决方法是,在退出函数之前,将不使用的局部变量全部删除。

内存泄漏: 程序的运行需要内存。对于持续运行的服务进程,必须及时释放不在用到的内存,否则占用越来越高,轻则影响系统性能,重则导致进程崩溃。不在用到的内存。没有及时释放,就叫做内存泄漏。

什么是作用域链?

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即 arguments 对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。

作用域链是在调用函数时,创建函数上下文,生成的作用域链。

对vue生命周期的理解

开场可以这么说,vue实例从创建到销毁的过程就是生命周期。即指从创建、初始化数据、编译模板、挂载Dom到渲染、更新到渲染、销毁等一系列过程。它主要分为8个阶段,创建前后、载入前后、更新前后、销毁前后以及一些特殊场景的生命周期(activated keep-alive缓存的组件激活时、deactivated keep-alive缓存的组件停用时调用、errorCapured 捕获一个来自子孙组件时的错误时调用),在说一下vue生命周期的整体流程。如图
在这里插入图片描述

说一下在createed和mouted获取数据的区别?

  • 在created获取数据,是在组件实例一旦创建完成的时候,立刻调用这时候页面dom节点还未生成。
  • mounted 是在页面dom节点渲染完毕之后就立刻执行的

两者的相同点是都能拿到实例对象的属性和方法,但是如果放在mounted请求,有可能导致页面闪动,但是如果在页面加载前完成就不会出现此情况。

vue数据绑定的理解

首先要了解vue的响应式原理:

  1. vue会遍历此data中对象所有的属性
  2. 并使用Object。defineProperty把这些属性全部转化为getter/setter
  3. 而每个组件实例都有watcher对象
  4. watcher对象它会在组件渲染的过程中把属性记录为依赖
  5. 之后当依赖项的setter被调用时候,会通知watcher重新计算,从而导致使它关联的组件得意更新

以上回答也是不行的,我们要抓住响应式原理中三个最最要的对象:

Observer、Wathcer、Dep

这三个对象的含义分别是:

Observer对象:vue的数据对象在初始化过程中转换为Observer对象。

Watcher对象:将模板和Observer对象结合在一起生成Watcher实例,Watcher是定阅者。

Dep对象:Watcher对象和Observer对象之间纽带,每一个Observer都有一个Dep实例,用来储存订阅者Watcher。

当属性变化时会执行主题对象Oberver的dep.notify方法,这个方法会遍历订阅者Watcehr列表向其发送消息。watcher会执行run方法去更新视图。

接着我们需要补充的是:

模板编译过程中的指令和数据绑定都会生成Watcher实例,vm实例中的watce属性也会生成Watcher实例。
具体总结看下图:
在这里插入图片描述

webpack中的loader和plugin的区别

首先,loader是什么?
loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
plugin又是什么?
在webpack运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果。
那有什么区别?
对于loader,它是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.less转换为A.css,单纯的文件转换过程。
plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务。

基本数据类型和引用数据类型的区别

首先来说一下基本数据类型。

  • 基本数据类型的值是不可变的,这里你就可以联想到,是不是所有关于字符串和数字的方法,都是带有返回值的,而不是改变原字符串或数字。

  • 基本数据类型不可以添加属性和方法,虽然不会报错,但也只是一瞬间转为了相应包装对象,操作完又转化回原基本数据类型,不会保存结果。

  • 基本数据类型的赋值是简单赋值,基本数据类型的比较是值的比较。

  • 基本数据类型是存放在栈区的。
    下面来说一下,引用数据类型。

  • 引用类型的值是可以改变的,例如对象就可以通过修改对象属性值更改对象。

  • 引用类型可以添加属性和方法。

  • 引用类型的赋值是对象引用,即声明的变量标识符,存储的只是对象的指针地址。

  • 引用类型的比较是引用(指针地址)的比较。

  • 引用类型是同时保存在栈区和堆区中的,栈区保存变量标识符和指向堆内存的地址

var 和let和const的区别

从以下三个方面来说:

  • 第一点:变量提升方面。
    var声明的变量存在变量提升,也就是变量可以在声明之前调用,值为undefined。

let和const不存在变量提升问题即它们所声明的变量一定要在声明后使用,否则报错。注意,这里的let和const,其实是有提升的,只不过是let和const具有一个暂时性死区的概念,也就是没有到其赋值时,之前就不能用。

  • 第二点:块级作用域方面。
    ? var不存在块级作用域,let和const存在块级作用域。

  • 第三点:声明方面。
    ? var允许重复声明变量,let和const在同一作用域内,不允许重复声明变量。其中const声明一个只读的常量,因此,其声明时就一定要赋值,不然报错。常量一旦声明,它的值就不能改变。

可能面试官会问你:如何使const声明的对象内属性不可变,只可读呢?我们要知道,如果const声明了一个对象,对象里的属性是可以改变的。来看这样一段代码,因为const声明的obj只是保存着其对象的引用地址,只要地址不变,就不会出错。
接着,我们使用Object.freeze(obj) 冻结obj,就能使其内的属性不可变,但它有一定的局限性,就是obj对象中要是有属性是对象,该对象内属性还能改变,要使全不可变,就需要使用递归等方式一层一层全部冻结。

ajax、fetch、axios的区别

Ajax是什么,Ajax是Asynchronous JavaScript and XML的缩写。现也就是,允许浏览器与服务器通信而无须刷新当前页面的技术都被叫做Ajax。核心使用XMLHttpRequest对象。
axios是什么,axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。
fetch是什么,Fetch被称为下一代Ajax技术,采用Promise方式来处理数据。是一种简洁明了的API,比XMLHttpRequest更加简单易用。
所以其主要区别是 axios、fetch请求后都支持Promise对象API,ajax只能用回调函数。

ansyc和defer的区别

在script标签内有这两个属性,async和defer。
defer,中文意思是延迟。用途是表示脚本会被延迟到整个页面都解析完毕后再运行。因此,在

ansyc await 对比promise的区别

首先来说一下async await的优点。
它做到了真正的串行的同步写法,代码阅读相对容易。对于条件语句和其他流程语句比较友好,可以直接写到判断条件里面。处理复杂流程时,在代码清晰度方面有优势。
缺点就是。
无法处理promise返回的reject对象,要借助try catch。用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。try catch内部的变量无法传递给下一个try catch。Promise和then catch内部定义的变量,能通过then链条的参数传递到下一个then catch,但是async await的try内部的变量,如果用let和const定义则无法传递到下一个try catch,只能在外层作用域先定义好。但async await确确实实是解决了promise一些问题的。更加灵活的处理异步。
最后来说一下,promise的一些问题。
一旦执行,无法中途取消,链式调用多个then中间不能随便跳出来。错误无法在外部被捕捉到,只能在内部进行预判处理,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。Promise内部如何执行,监测起来很难,当处于pending状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成。

cookie和session的区别

cookies和session的区别。

  • 第一点,存储位置不同。
    cookie的数据信息存放在客户端浏览器上,session的数据信息存放在服务器上。
  • 第二点,存储容量不同。
    单个cookie保存的数据小于等于4KB,一个站点最多保存20个Cookie,而对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。
  • 第三点,存储方式不同。
    cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。
  • 第四点,隐私策略不同。
    cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的,而session存储在服务器上,对客户端是透明的,不存在敏感信息泄漏的风险。
  • 第五点,有效期不同。
    开发可以通过设置cookie的属性,达到使cookie长期有效的效果。session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。
  • 第六点,服务器压力不同。
    cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。
  • 第七点,跨域支持不同。
    cookie支持跨域名访问。session不支持跨域名访问。
    参见我的另一篇cookie和session的区别博文

get和post的区别

GET 是将参数写在 URL 中问号(?)的后面,并用and符号(&)分隔不同参数;而 POST 是将信息存放在 Message Body 中传送,参数‘不会’显示在 URL 中,Restful规范中是这样,但post在有需要时可以把参数放URL里。GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。
GET请求提交的数据有长度限制,POST请求没有内容长度限制。HTTP 协议本身没有限制 URL 及正文长度,对 URL 的限制大多是浏览器和服务器的原因。
GET请求返回的内容会被浏览器缓存起来。而每次提交POST请求,浏览器不会缓存POST请求返回的内容。
GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写。
关于安全性,GET 请求方式从浏览器的 URL 地址就可以看到参数;所以post更安全,其实无论是 GET 还是 POST 其实都是不安全的,因为 HTTP 协议是明文传输,只要拦截封包便能轻易获取重要信息。想要安全传输资料,必须使用 SSL/TLS来加密封包,也就是 HTTPS。

那为什么推荐使用post来处理敏感数据呢?

因为get的记录会保存在浏览器,上传日志中,而使用Post,因为数据不会记录存储在浏览器的记录和网址访问记录中,这样会有更大的安全性。
这里有一个误区,说GET产生一个TCP数据包;POST产生两个TCP数据包。
其说法是,对于GET方式的请求,浏览器会把http header和data一并发送出去,服务端响应200,请求成功。
对于POST方式的请求,浏览器会先发送http header给服务端,告诉服务端等一下会有数据过来,服务端响应100 continue,告诉浏览器我已经准备接收数据,浏览器再post发送一个data给服务端,服务端响应200,请求成功。
上面所说的post会比get多一个tcp包其实不太严谨。多发的那个expect 100 continue header报文,是由客户端对http的post和get的请求策略决定的,目的是为了避免浪费资源,如带宽,数据传输消耗的时间等等。所以客户端会在发送header的时候添加expect 100去探探路,如果失败了就不用继续发送data,从而减少了资源的浪费。所以是否再发送一个包取决了客户端的实现策略,和get/post并没什么关系。有的客户端比如fireFox就只发送一个包。

参见我的另一篇tcp/ip博文

px em rem vw vh的区别

px: px就是pixel的缩写,意为像素。px就是一张图片最小的一个点,一张位图就是千千万万的这样的点构成的。
em: 参考物是父元素的font-size,具有继承的特点。如果自身定义了font-size按自身来计算,浏览器默认字体是16px,整个页面内1em不是一个固定的值。
rem: css3新单位,相对于根元素html(网页)的font-size,不会像em那样,依赖于父元素的字体大小,而造成混乱。
vw: css3新单位,viewpoint width的缩写,视窗宽度,1vw等于视窗宽度的1%。
举个例子:浏览器宽度1200px, 1 vw = 1200px/100 = 12 px。
vh: css3新单位,viewpoint height的缩写,视窗高度,1vh等于视窗高度的1%。
举个例子:浏览器高度900px, 1 vh = 900px/100 = 9 px。

http和ttpps的区别

1,HTTP 是明文传输,数据都是未加密的,安全性较差,HTTPS即SSL+HTTP,数据传输过程是加密的,安全性较好。
2,使用 HTTPS 协议需要到 CA申请证书,CA就是Certificate Authority,数字证书认证机构;一般免费证书较少,因而需要一定费用。
3,HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上SSL握手需要的 9 个包,所以一共是 12 个包。
4,HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
5,HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。

什么是http无状态协议?如何客服http无状态协议的缺陷?

无状态协议对于事物处理没有记忆能力,缺少状态,意味着如果后续需要处理,需要前面提供的信息。克服无状态协议缺陷的办法是方向代理(Reverse Proxy)是指通过代理服务器来接受互联网上的连接请求。然后请求转发给内部网络上的服务器,并把从服务器上得到的结果返回给互联网上请求连接的客户端,此时代理服务对外就表现为一个反向代理服务器

http与https有什么联系?他们的端口号是多少?

http通常承载与tcp之上,在http和tcp之间添加一个安全协议层(ssl或tsl)这时候就成了我们常说的https。http默认端口号为80,https默认端口号为443

为什么https更安全

在网络请求中有很多服务器,路由器的转发其中的节点可能篡改信息,如果使用https秘钥在终点站才有,https之所以比http更安全,是因为他里用了ssl/tsl协议传输,它包含证书、卸载、流量转发、负载均衡、页面适配、浏览器适配、refer传输保障了传输过程中的安全性

js中的栈和堆和队列的区别

  1. 栈和堆的区别

栈先进后出,动态分配空间,一般由程序员分配释放,若程序员不释放,程序结束时可能由os回收,分配方式类似链表。堆先进先出,由操作系统自动分配释放 存放函数的参数值,局部变量的值等,其操作方式类似于数据结构中的栈。

  1. 栈和队列的区别

栈只允许表尾一端进行插入和删除,队列只允许在表尾一端进行插入,在表头一端进行删除,栈是先进后出,队列是先进先出

tcp和udp的区别

  • tcp是面向连接的,udp是无连接的即发送数据前不需要提前建立连接。
  • tcp提供可靠的服务。也就是说通过tcp连接传送的数据。无差错、不丢失、不重复且按序到达。udp尽最大的努力交付,即不保证可靠交付。
  • 并且因为tcp可靠 面向连接。不会丢失数据,因此适合大数据量的交换。
  • tcp是面向字节流,udp是面向报文,并且它在网络出现拥塞不会使得发送速率降低,因此会出现丢包,对实时的应用比如ip电话和视频会议等。
  • tcp只能是1对1的,而udp支持1对1、1对多,tcp的头部较大为20字节而udp只有8字节。

建立TCP需要三次握手才能建立,而断开连接则需要四次握手。整个过程如下图所示:

在这里插入图片描述
先来看看如何建立连接的。
在这里插入图片描述首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。

那如何断开连接呢?简单的过程如下:
在这里插入图片描述
【注意】中断连接端可以是Client端,也可以是Server端。

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

整个过程Client端所经历的状态如下:
在这里插入图片描述而Server端所经历的过程如下:
在这里插入图片描述

在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
转载自

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:31:56  更:2021-11-30 15:31:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 1:25:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码