到页面加载完成的过程中都发生了什么事情

从输入 U奥迪Q3L 到页面加载成功的进度中都爆发了哪些工作?

2015/10/03 · HTML5,
JavaScript · 6
评论 ·
HTTP,
浏览器

原来的小说出处:
百度FEX/吴多益(@吴多益)   

背景  本文来源于事先笔者发的一篇乐乎:

图片 1

而是写那篇小说并不是为了帮大家准备面试,而是想借这道题来介绍总括机和网络的基础知识,让读者领会它们中间是什么关联起来的。

为了有利于驾驭,笔者将全方位进度分成了多个难点来展开。

从输入 UGL450L
到页面加载成功的进度中都产生了什么业务–div.io

作业完全没有设想中那么不难,上面链接里面包车型大巴事物你全部看懂,你曾经是大牛了

从输入 U君越L 到页面加载成功的长河中都爆发了哪些业务?

前段时间抽空读了《图解HTTP》完整跟《HTTP权威指南》的前半部分,恰还好网上看到这一个话题,细想一番后对待一网民的篇章发现本身有不少遗漏。特意倒车简书上的那篇小说!

先是个难点:从输入 U大切诺基L 到浏览器接收的进程中发生了什么样业务?

从输入 U大切诺基L
到页面加载成功的历程中都发生了什么事情?–get社区

从输入 U索罗德L 到页面加载成功的历程中都产生了怎么着工作? –
FEX

1.浏览器接收UKugaL

UGL450L包罗的音讯:协议、网络地址:端口号、能源路径、查询字符串?、片段标识符#

从触屏到 CPU

第二是「输入
U普拉多L」,大多数人的第①反应会是键盘,可是为了与时俱进,这里将介绍触摸屏设备的竞相。

触摸屏一种传感器,近来基本上是遵照电容(Capacitive)来贯彻的,从前都是直接覆盖在显示器上的,然则近日面世了
3 种嵌入到显示器中的技术,第壹种是 BlackBerry 5 的 In-cell,它能减小了 0.5
分米的薄厚,第①种是Samsung选用的 On-cell 技术,第两种是国内厂商喜欢用的
OGS
全贴合技术,具体细节能够翻阅那篇小说。

当手指在那么些传感器上触摸时,有个别电子会传递到手上,从而导致该区域的电压变化,触摸屏控制器芯片遵照这几个变化就能总计出所触摸的职位,然后经过总线接口将信号传到
CPU 的引脚上。

以 Nexus 5 为例,它所运用的触屏控制器是 Synaptics
S3350B,总线接口为 I²C,以下是
Synaptics
触摸屏和总计机连接的演示:图片 2

左侧是电脑,右侧是触摸屏控制器,中间的 SDA 和 SCL 连线正是 I²C
总线接口。

2.将UCRUISERL与缓存举办比对即使请求的页面在缓存中且未过期,则一向开始展览第9步

缓存分为彻底缓存和缓存协商,那里的认但是不是过期是指彻底缓存(缓存失效在此以前不再必要跟服务器交互)。

2.1 彻底缓存的体制(http首部字段):cache-control,Expires

–Expires是三个纯属时间,即服务器时间。浏览器检查当前时间,假若还没到失效时间就径直利用缓存文件。不过该方法存在1个难点:服务器时间与客户端时间大概不一致等。因而该字段已经很少使用,以往主导用cache-control实行判断。

–cache-control中的max-age保存3个对即刻间。例如Cache-Control: max-age =
484200,表示浏览器收到文件后,缓存在484200s内均有效。
倘若同时存在cache-control和Expires,浏览器总是优先利用cache-control。

cache-control还有其他指令:

(请求/响应指令)

no-cache,使用缓存前必须和服务器进行确认,也就是需要发起请求。

no-store,不缓存;

(响应指令)

public,缓存文件保存在缓存服务器上,且其他用户也可以访问;

private,只有特定用户才能访问该缓存资源。

2.2
当缓存过期时,浏览器会向服务器发起呼吁询问财富是或不是确实过期,那正是缓存协商。对应http首部字段:last-modified,Etag

–last-modified是率先次呼吁财富时,服务器重回的字段,表示最后一遍立异的时日。下1回浏览器请求财富时就发送if-modified-since字段。服务器用当地Last-modified时间与if-modified-since时间比较,假若不均等则觉得缓存已过期并重临新能源给浏览器;如若时间同一则发送304状态码,让浏览器继续应用缓存。当然,用该措施也存在难题,比如修改时间有浮动但实际内容没有转变,而服务器却再一次将能源发送给浏览器。所以,使用Etag进行判定更好。

–Etag:财富的实业标识(哈希字符串),当能源内容更新时,Etag会改变。服务器会咬定Etag是或不是发生变化,假使生成则赶回新财富,不然再次回到304。

缓存协商的过程需要发起一起HTTP请求,如果返回304则继续使用缓存。对于移动端一次请求还是有代价的,所以我们需要避免304。

对于很少进行更改的静态文件,可以在文件名中加入版本号,如get.v1.js,并且把Cache-Control的max-age设置成一年半载,这样就不会发送请求。

需要注意的是,当这些文件更新的时候,我们需要更新其版本号,这样浏览器才会到服务器下载新资源。

图片 3

CPU 内部的处理

运动装备中的 CPU 并不是一个独立的芯片,而是和 GPU
等芯片集成在一起,被叫做 SoC(片上系统)。

前方提到了触屏和 CPU
的连年,那几个一连和超越伍分叁处理器内部的总是一样,都是因而电气信号来拓展通信的,也正是电压高低的转变,如上面的时序图:图片 4

在时钟的操纵下,那些电流会经过 MOSFET 晶体管,晶体管中包涵N 型半导体收音机和 P 型半导体收音机,通过电压就能控制线路开闭,然后这么些 MOSFET
构成了 CMOS,接着再由 CMOS
达成「与」「或」「非」等逻辑电路门,最终由逻辑电路门上就能促成加法、位移等计算,全体如下图所示(来自《总计机种类布局》):图片 5

除了计算,在 CPU
中还要求存款和储蓄单元来加载和储存数据,那一个存款和储蓄单元一般通过触发器(Flip-flop)来达成,称为寄存器。

如上那么些概念都相比抽象,推荐阅读「How to Build an 8-Bit
Computer到页面加载完成的过程中都发生了什么事情。」那篇文章,作者依据晶体管、二极管、电容等原件制作了1个8 位的处理器,帮衬简单汇编指令和结果输出,尽管现代 CPU
的兑现要比那个纷纷得多,但基本原理还是一样的。

除此以外其实本身也是刚开始攻读 CPU
芯片的落实,所以就不在那误人子弟了,感兴趣的读者请阅读本节背后推荐的图书。

3.借使网络地址不是三个 IP 地址,通过DNS解析域名重临一个IP地址

3.1 DNS协议:

DNS数据库是域名和IP地址相互映射的一个分布式数据库,DNS协议用来将域名转换为IP地址,它运转在UDP磋商之上。为何选拔UDP而非TCP?原因如下:UDP无需三番五次,时效性更好,举办贰遍查询只需求八个DNS包。而TCP需求先用三个包建立连接,再用3个DNS包举办查询,最终用伍个包断开连接,连接开支远大于查询自身,简单让DNS服务器不堪重负。

3.2 DNS查询:

操作系统会先反省本地hosts文件是还是不是有那个网址映射关系,倘若有就调用这些IP地址映射,达成域名解析。

不然,查找本地DNS解析器缓存,借使查找到则赶回。

不然,查找本地DNS服务器,假诺查找到则赶回。

要不,1)未用转载方式,按根域服务器
->超级域,.com->第贰层域,example.com
->子域,www.example.com的相继找到IP地址。2)用倒脚形式,按上一流DNS服务器->上上级->….逐级向上查询找到IP地址。

从 CPU 到操作系统内核

眼下说到触屏控制器将电气信号发送到 CPU 对应的引脚上,接着就会触发 CPU
的中止机制,以 Linux
为例,每一个外部设备都有一标识符,称为中断请求(I奥迪Q7Q)号,能够由此 /proc/interrupts 文件来查看系统中具有设施的间歇请求号,以下是
Nexus 7 (二零一三) 的一部分结果:

shell@flo:/ $ cat /proc/interrupts CPU0 17: 0 GIC dg_timer 294: 1973609
msmgpio elan-ktf3k 314: 679 msmgpio KEY_POWER

1
2
3
4
5
shell@flo:/ $ cat /proc/interrupts
            CPU0
  17:          0       GIC  dg_timer
294:    1973609   msmgpio  elan-ktf3k
314:        679   msmgpio  KEY_POWER

因为 Nexus 7 使用了 ELAN 的触屏控制器,所以结果中的 elan-ktf3k
就是触屏的中断请求音信,个中 294 是中断号,1972609
是触发的次数(手指单击时会发生一次中断,但滑动时会发生数十次暂停)。

为了简化那里不考虑优先级难点,以 A奥迪Q5Mv7
架构的总括机为例,当刹车产生时,CPU
会停下当前运营的程序,保存当前履行情况(如 PC 值),进入 I奥迪Q7Q
状态),然后跳转到对应的间歇处理程序执行,这一个顺序一般由第一方内核驱动来达成,比如后边提到的
Nexus 7
的驱动力源码在那边 touchscreen/ektf3k.c。

本条驱动程序将读取 I²C
总线中传播的职位数据,然后经过基础的 input_report_abs 等方式记录触屏按下坐标等新闻,最终由基本中的input
子模块将那么些音讯都写进 /dev/input/event0 那些装置文件中,比如上面展示了1回触摸事件所发生的音信:

130|shell@flo:/ $ getevent -lt /dev/input/event0 [ 414624.658986]
EV_ABS ABS_MT_TRACKING_ID 0000835c [ 414624.659017] EV_ABS
ABS_MT_TOUCH_MAJOR 0000000b [ 414624.659047] EV_ABS
ABS_MT_PRESSURE 0000001d [ 414624.659047] EV_ABS
ABS_MT_POSITION_X 000003f0 [ 414624.659078] EV_ABS
ABS_MT_POSITION_Y 00000588 [ 414624.659078] EV_SYN SYN_REPORT
00000000 [ 414624.699239] EV_ABS ABS_MT_TRACKING_ID ffffffff [
414624.699270] EV_SYN SYN_REPORT 00000000

1
2
3
4
5
6
7
8
9
130|shell@flo:/ $ getevent -lt /dev/input/event0
[  414624.658986] EV_ABS       ABS_MT_TRACKING_ID   0000835c
[  414624.659017] EV_ABS       ABS_MT_TOUCH_MAJOR   0000000b
[  414624.659047] EV_ABS       ABS_MT_PRESSURE      0000001d
[  414624.659047] EV_ABS       ABS_MT_POSITION_X    000003f0
[  414624.659078] EV_ABS       ABS_MT_POSITION_Y    00000588
[  414624.659078] EV_SYN       SYN_REPORT           00000000
[  414624.699239] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
[  414624.699270] EV_SYN       SYN_REPORT           00000000

4.浏览器与服务器通过二遍握手(SYN,SYN/ACK,ACK)建立TCP 连接

图片 6

怎么需求开始展览1回握手,而不是五回握手?

缘由是三次握手不可靠。比如,浏览器发送三个连续请求包A,但包A在半路上堵车了,浏览器就认为包A丢失了,所以重复产生2个请求包B给服务器。服务器收到请求,建立连接。两端举行通信,停止后关门连接。可是此时,包A到达了服务器,服务器不知道这是二个无效的包,所以举行响应。那时三次握手已经成功,两端就建立起三个空头的接连。但浏览器认为自身没发出请求,所以不会回复,那样就让服务器白白等待答复,浪费了服务器财富。而3回握手的体制下,浏览器知道自个儿并没有请求连接,会发送拒绝包给服务器,服务器收到回复后也会截止此次不行的一而再。

从操作系统 GUI 到浏览器

前方提到 Linux
内核已经成功了对硬件的架空,别的程序只要求通过监听 /dev/input/event0 文件的成形就能知晓用户展开了什么触摸操作,可是如若各种程序都这么抓实在太麻烦了,所以在图像操作系统中都会包含GUI 框架来便宜应用程序开发,比如 Linux 下有名的 X。

但 Android 并从未选取 X,而是本身达成了一套 GUI
框架,个中有个 EventHub 的服务会通过 epoll 形式监听 /dev/input/ 目录下的公文,然后将那么些新闻传递到
Android
的窗口管理服务(WindowManagerService)中,它会依据职分音信来查找相应的
app,然后调用在那之中的监听函数(如 onTouch 等)。

就像是此,大家解答了第二个难题,可是由于时间有限,那里大致了很多细节,想进一步深造的读者推荐阅读以下书籍。

5.浏览器向服务器发送HTTP请求。

数量通过应用层、传输层、网络层、物理层逐层封装,传输到下四个目标地。

其中,每一层的作用如下。

应用层:为应用进程提供服务,加应用层首部封装为协议数据单元。

传输层:实现端到端通信,加TCP首部封装为数据包,TCP控制了数据包的发送序列的产生,不断的调整发送序列,实现流控和数据完整。

网络层:转发分组并选择路由;加IP首部封装为IP分组。

数据链路层:相邻的节点间的数据传输;加首部[mac地址]和尾部封装为帧。

物理层:具体物理媒介中的数据传送,数据转换为比特流。

下二个指标地接受到数码后,从物理层获得数码然后通过逐层的解包 到 链路层
到 互连网层,然后伊始上述的拍卖,在经互连网层 链路层
物理层将数据封装好继续传往下3个地点。

到达最后目标地,再经过5层结构,逐层剥离,最后将数据送到目标主机的目标端口。

扩张学习

  • 《微型总结机体系布局》
  • 《电脑系列布局:量化研商格局》
  • 《电脑组成与统一筹划:硬件/软件接口》
  • 《编码》
  • 《CPU自制入门》
  • 《操作系统概念》
  • 《AEscortMv7-ARAV4种类布局参考手册》
  • 《Linux内核设计与达成》
  • 《通晓Linux设备驱动程序开发》

6.服务器收到请求,从它的文书档案空间中追寻财富并回到HTTP响应。

其次个难点:浏览器怎么着向网卡发送数据?

7.浏览器接受 HTTP 响应,检查 HTTP header 里的状态码,并做出分化的处理情势。

比如404呈现错误页面,304利用缓存,200下一步解码和渲染,
204页面不会发生更新。

常见状态码:200 ok, 204 no content, 206 partial content

301 moved permanently(能源已分配新的uri),302
found(此次使用新uri访问),303 see other(以get定向到另贰个uri),304 not
modified, 307 temporary redirect(不会从post改为get)

400 bad request,402 unauthorized,403 forbidden, 404 not found

500 internal server error,503 service unavailable

从浏览器到浏览器内核

前方提到操作系统 GUI
将输入事件传递到了浏览器中,在那进度中,浏览器恐怕会做一些预处理,比如
Chrome
会依照历史计算来预估所输入字符对应的网站,比如输入了「ba」,依据在此之前的历史发现
百分之九十 的概率会造访「www.baidu.com 」,因而就会在输入回车前就及时开首建立
TCP 链接甚至渲染了,那之中还有许多别样策略,感兴趣的读者推荐阅读 High
Performance Networking in
Chrome。

随后是输入 U智跑L 后的「回车」,那时浏览器会对 U途乐L
进行自小编批评,首先判断协议,假诺是 http 就依照 Web 来处理,其余还会对那些U奇骏L
举行安检,然后径直调用浏览器内核中的对应措施,比如 WebView 中的
loadUrl 方法。

在浏览器内核中会先查看缓存,然后设置 UA 等 HTTP
音讯,接着调用差别平台下互连网请求的办法。

须求小心浏览器和浏览器内核是见仁见智的概念,浏览器指的是
Chrome、Firefox,而浏览器内核则是
Blink、Gecko,浏览器内核只承担渲染,GUI
及网络连接等跨平台工作则是浏览器达成的

8.如若是足以缓存的,那几个响应则会被储存起来。

基于首部字段判断是或不是开始展览缓存。例如,Cache-Control,
no-cache(每一次使用缓存前和服务器确认),no-store 相对禁止缓存

HTTP 请求的出殡

因为网络的最底层完成是和基础相关的,所以这一局地须要针对差别平台实行拍卖,从应用层角度看首要做两件事情:通过
DNS 查询 IP、通过 Socket 发送数据,接下去就各自介绍这两下边包车型客车剧情。

9.解码

9.1
浏览器得到index.html文件后,就开端解析在这之中的html代码,遭遇js/css/image等静态能源时,就向劳动器端去央浼下载

9.2 解析成对应的树形数据结构DOM树、CSS规则树,Javascript脚本通过DOM
API和CSSOM API来操作DOM树、CSS规则树。

DNS 查询

应用程序可以直接调用 Libc
提供的 getaddrinfo() 方法来兑现
DNS 查询。

DNS 查询其实是基于 UDP
来促成的,这里大家透过3个实际事例来明白它的追寻进程,以下是采用 dig +trace fex.baidu.com 命令获得的结果(省略了部分):

; <<>> DiG 9.8.3-P1 <<>> +trace fex.baidu.com ;;
global options: +cmd . 11157 IN NS g.root-servers.net. . 11157 IN NS
i.root-servers.net. . 11157 IN NS j.root-servers.net. . 11157 IN NS
a.root-servers.net. . 11157 IN NS l.root-servers.net. ;; Received 228
bytes from 8.8.8.8#53(8.8.8.8) in 220 ms com. 172800 IN NS
a.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN
NS m.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800
IN NS e.gtld-servers.net. ;; Received 503 bytes from
192.36.148.17#53(192.36.148.17) in 185 ms baidu.com. 172800 IN NS
dns.baidu.com. baidu.com. 172800 IN NS ns2.baidu.com. baidu.com. 172800
IN NS ns3.baidu.com. baidu.com. 172800 IN NS ns4.baidu.com. baidu.com.
172800 IN NS ns7.baidu.com. ;; Received 201 bytes from
192.48.79.30#53(192.48.79.30) in 1237 ms fex.baidu.com. 7200 IN CNAME
fexteam.duapp.com. fexteam.duapp.com. 300 IN CNAME duapp.n.shifen.com.
n.shifen.com. 86400 IN NS ns1.n.shifen.com. n.shifen.com. 86400 IN NS
ns4.n.shifen.com. n.shifen.com. 86400 IN NS ns2.n.shifen.com.
n.shifen.com. 86400 IN NS ns5.n.shifen.com. n.shifen.com. 86400 IN NS
ns3.n.shifen.com. ;; Received 258 bytes from
61.135.165.235#53(61.135.165.235) in 2 ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
; <<>> DiG 9.8.3-P1 <<>> +trace fex.baidu.com
;; global options: +cmd
.           11157   IN  NS  g.root-servers.net.
.           11157   IN  NS  i.root-servers.net.
.           11157   IN  NS  j.root-servers.net.
.           11157   IN  NS  a.root-servers.net.
.           11157   IN  NS  l.root-servers.net.
;; Received 228 bytes from 8.8.8.8#53(8.8.8.8) in 220 ms
 
com.            172800  IN  NS  a.gtld-servers.net.
com.            172800  IN  NS  c.gtld-servers.net.
com.            172800  IN  NS  m.gtld-servers.net.
com.            172800  IN  NS  h.gtld-servers.net.
com.            172800  IN  NS  e.gtld-servers.net.
;; Received 503 bytes from 192.36.148.17#53(192.36.148.17) in 185 ms
 
baidu.com.      172800  IN  NS  dns.baidu.com.
baidu.com.      172800  IN  NS  ns2.baidu.com.
baidu.com.      172800  IN  NS  ns3.baidu.com.
baidu.com.      172800  IN  NS  ns4.baidu.com.
baidu.com.      172800  IN  NS  ns7.baidu.com.
;; Received 201 bytes from 192.48.79.30#53(192.48.79.30) in 1237 ms
 
fex.baidu.com.      7200    IN  CNAME   fexteam.duapp.com.
fexteam.duapp.com.  300 IN  CNAME   duapp.n.shifen.com.
n.shifen.com.       86400   IN  NS  ns1.n.shifen.com.
n.shifen.com.       86400   IN  NS  ns4.n.shifen.com.
n.shifen.com.       86400   IN  NS  ns2.n.shifen.com.
n.shifen.com.       86400   IN  NS  ns5.n.shifen.com.
n.shifen.com.       86400   IN  NS  ns3.n.shifen.com.
;; Received 258 bytes from 61.135.165.235#53(61.135.165.235) in 2 ms

能够见见那是两个逐步裁减范围的追寻进度,首先由本机所设置的 DNS
服务器(8.8.8.8)向 DNS 根节点查询负责 .com
区域的域务器,然后经过内部贰个承受 .com 的服务器询问负责 baidu.com
的服务器,最终由当中贰个 baidu.com 的域名服务器询问 fex.baidu.com
域名的地方。

只怕你在查询有个别域名的时会发现和方面不同,最底将见到有个意外的服务器超过重临结果。。。

此间为了便于描述,忽略了诸多例外的状态,比如 127.0.0.1
其实走的是 loopback,和网卡设备没关系;比如
Chrome 会在浏览器运营的时预先查询 10 个你有也许访问的域名;还有 Hosts
文件、缓存时间 TTL(Time to live)的震慑等。

10.渲染

10.1 总计CSS样式(JS可动态修改dom或css,进一步改变渲染树和散布)

10.2
构建渲染树(Repaint:显示屏的一有的要重画,比如某些CSS的背景象变了,成分的几何尺寸没有变。Reflow:几何尺寸变了,大家要求再一次验证并盘算Render
Tree。)

10.3 确认布局(定位坐标和大小,是或不是换行,各样position, overflow,
z-index属性 ……)

10.4 绘制(调用操作系统Native
GUI的API绘制,将各种节点转化为实在像素绘制到视口上)

透过 Socket 发送数据

有了 IP 地址,就可以透过 Socket API 来发送数据了,那时能够挑选 TCP 或
UDP 协议,具体使用办法那里就不介绍了,推荐阅读 Beej’s Guide to Network
Programming。

HTTP 常用的是 TCP 协议,由于 TCP
协议的切实细节随处都能来看,所以本文就不介绍了,那里谈一下 TCP 的
Head-of-line blocking 难题:要是客户端的发送了 3 个 TCP
片段(segments),编号分别是 ① 、贰 、3,若是编号为 1
的包传输时丢了,固然编号 2 和 3 已经到达也只可以等待,因为 TCP
协议必要有限支撑顺序,那一个标题在 HTTP pipelining 下更要紧,因为 HTTP
pipelining 能够让多个 HTTP 请求通过一个 TCP
发送,比如发送两张图纸,大概第一张图纸的多寡已经全接受了,但还得等率先张图纸的数据传到。

为了消除 TCP 协和的性质难点,Chrome
团队二零一八年提议了 QUIC 协议,它是依据UDP 达成的保证传输,比起 TCP,它能减小过多来来往往(round
trip)时间,还有前向纠错码(Forward Error Correction)等成效。近来 谷歌(Google)Plus、 Gmail、谷歌(Google) Search、blogspot、Youtube 等大致大多数 谷歌产品都在行使 QUIC,能够经过 chrome://net-internals/#spdy 页面来发现。

尽管如此近年来除了 谷歌 还没人用 QUIC,但自笔者认为挺有前景的,因为优化 TCP
必要升级系统基本(比如 Fast
Open)。

浏览器对同三个域名有连接数限制,大部是
6,小编在此以前认为将那么些连接数改大后会升高品质,但实际并不是那般的,Chrome
团队有做超过实际验,发现从 6 改成 10
后质量反而下跌了,造成那一个景况的要素有为数不少,如成立连接的成本、拥挤堵塞控制等题材,而像
SPDY、HTTP 2.0 协议就算只利用三个 TCP
连接来传输数据,但质量反而更好,而且还能够落实请求优先级。

除此以外,因为 HTTP 请求是纯文本格式的,所以在 TCP 的数额段中能够一直解析
HTTP 的公文,假设发现。。。

11.闭馆TCP连接或三番五次保证接二连三

经过7遍挥手关闭连接(FIN ACK, ACK, FIN ACK, ACK)。

图片 7

缘何要求展开肆遍挥手?

第3次挥手是浏览器发完数据后,发送FIN请求断开连接。第三遍挥手是服务器发送ACK表示同意,如若在那2遍服务器也发送FIN请求断开连接就如也一向不不妥,但考虑到服务器可能还有多少要发送,所以服务器发送FIN应该放在第二遍挥手中。那样浏览器须要重临ACK表示同意,也等于第⑩次挥手。

简言之,一端断开连接需求五回挥手(请求和回复),两端断开连接就必要8次挥手了。

相关文章