- 一、基础知识
- 二、应用层
- 1、HTTP的状态码有哪些?
- 2、HTTP的请求方法有哪些?
- 3、HTTP是什么,描述一下?
- 4、HTTP是用于从互联网服务器传输超文本到本地浏览器的协议 ,这种说法正确吗?
- 5、HTTP常见字段有哪些?
- 6、说一下 GET 和 POST 的区别?
- 7、HTTP的优缺点?
- 8、说下 HTTP/1.1 的性能如何?
- 9、HTTP 与 HTTPS 有哪些区别?
- 10、HTTPS 解决了 HTTP 的哪些问题?
- 11、HTTPS 是如何解决 HTTP 的问题?
- 12、HTTPS 是如何建立连接的?其间交互了什么?
- 13、说说 HTTP/1.1 相比 HTTP/1.0 提高了什么性能?
- 14、HTTP/2 相比 HTTP/1.1 做了什么优化?
- 15、HTTP/2 有哪些缺陷?HTTP/3 做了哪些优化?
- 16、HTTP/1.1如何优化?
- 17、如何避免发送 HTTP 请求?
- 18、如何减少 HTTP 请求次数?
- 19、如何减少 HTTP 响应的数据大小?
- 20、HTTPS 如何优化?
- 三、传输层
- 1、TCP和UDP的区别?应用场景有哪些?
- 2、TCP的头部格式
- 3、为什么需要 TCP 协议?TCP 工作在哪一层?
- 4、什么是 TCP ?
- 5、什么是 TCP 连接?
- 6、如何唯一确定一个 TCP 连接呢?
- 7、有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是多少?
- 8、UDP头部格式
- 9、TCP 三次握手过程
- 10、为什么TCP是三次握手?不是两次、四次?
- 11、为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢?
- 12、初始序列号 ISN 是如何随机产生的?
- 13、既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢?
- 14、第一次握手丢失了,会发生什么?
- 15、第二次握手丢失了,会发生什么?
- 16、第三次握手丢失了,会发生什么?
- 17、什么是 SYN 攻击?如何避免 SYN 攻击?
- 18、TCP的四次挥手?
- 19、为什么挥手需要四次?
- 20、第一次挥手丢失了,会发生什么?
- 21、第二次挥手丢失了,会发生什么?
- 22、第三次挥手丢失了,会发生什么?
- 23、第四次挥手丢失了,会发生什么?
- 24、为什么 TIME_WAIT 等待的时间是 2MSL?
- 25、为什么需要 TIME_WAIT 状态?
- 26、TIME_WAIT 过多有什么危害?
- 27、如果已经建立了连接,但是客户端突然出现故障了怎么办?
- 28、如果已经建立了连接,但是客户端的进程崩溃会发生什么?
- 29、针对 TCP 应该如何 Socket 编程?
- 30、accept 发生在三次握手的哪一步?
- 31、客户端调用 close 了,连接是断开的流程是什么?
- 32、TCP 是面向连接的,那么连接是什么?
- 3、为什么要等待2MSL的时间才关闭?
- 4、TCP怎么保证传输过程的可靠性?
- 5、知道HTTPS的工作原理吗?
- 6、负载均衡有哪些实现方式?
- 7、TCP如何保证可靠性
- 8、怎么理解同步和阻塞?
- 9、谈一下你对Reactor模型的理解?
- 四、网络层
一、基础知识
1、TCP/IP 网络模型
(1)应用层
①当两个不同设备的应用需要通信的时候,应用就把应用数据传给传输层
②应用层只关心为用户提供应用功能,不用关心数据是如何传输
③应用层是工作在操作系统中的用户态,传输层及以下则工作在内核态
(2)传输层
①传输层为应用层提供网络支持
②有两个传输协议,分别是TCP和UDP
③当传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包
④当设备作为接收方时,传输层则要负责把数据包传给应用,但是一台设备上可能会有很多应用在接收或者传输数据,因此需要用一个编号将应用区分开来,这个编号就是端口
(3)网络层
①具备传输功能,负责将数据从一个设备传输到另一个设备
②常用的是 IP 协议,IP 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文,如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文
③IP地址分为网络号和主机号:一个是网络号,负责标识该 IP 地址是属于哪个子网的;一个是主机号,负责标识同一子网下的不同主机。
④IP 协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走,路由则是根据「下一个目的地」选择路径
(4)数据链路层
①标识网络中的设备,让数据在一个链路中传输,主要为网络层提供链路级别传输的服务
②每一台设备的网卡都会有一个 MAC 地址,它就是用来唯一标识设备的
③路由器计算出了下一个目的地 IP 地址,再通过 ARP 协议找到该目的地的 MAC 地址,这样就知道这个 IP 地址是哪个设备的了。
(5)物理层
①当数据准备要从设备发送到网络时,需要把数据包转换成电信号,让其可以在物理介质中传输
②为数据链路层提供二进制传输的服务
2、OSI参考模型
(1)应用层
负责给应用程序提供统一的接口
(2)表示层
负责把数据转换成兼容另一个系统能识别的格式
(3)会话层
负责建立、管理和终止表示层实体之间的通信会话
(4)传输层
负责端到端的数据传输
(5)网络层
负责数据的路由、转发、分片
(6)数据链路层
负责数据的封帧和差错检测,以及 MAC 寻址
(7)物理层
负责在物理网络中传输数据帧
二、应用层
1、HTTP的状态码有哪些?
2、HTTP的请求方法有哪些?
3、HTTP是什么,描述一下?
HTTP 是超文本传输协议。
(1)协议
HTTP是一个用在计算机的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方式(行为约定和规范)
(2)传输
①HTTP是一种双向协议;
②数据虽然是在 A 和 B 之间传输,但允许中间有中转与接力
③HTTP是一个在计算机世界里专门用来在两点之间传输数据的约定和规范
(3)超文本
超文本是文字、图片、视频等的混合体,最关键有超链接,能从一个超文本跳转到另外一个超文本(HTML是最常见的超文本)
HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。
4、HTTP是用于从互联网服务器传输超文本到本地浏览器的协议 ,这种说法正确吗?
不正确。也可以在服务器和服务器之间进行传输,这里修改为两点之间描述会更准确
5、HTTP常见字段有哪些?
(1)Host字段
客户端发送请求时,用来指定服务器的域名
(2)Content-Length字段
服务器在返回数据时,会有 Content-Length 字段,表明本次回应的数据长度
(3)Connection字段
最常用于客户端要求服务器使用TCP持久连接,以便其他请求复用
①HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为Keep-Alive
②一个可以复用的TCP连接就建立了,直到客户端或服务器主动关闭连接(这不是标准字段)
(4)Content-Type字段
用于服务器回应时,告诉客户端,本次数据是什么格式
①上面的类型表明,发送的是网页,而且编码是UTF-8
②客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式,“Accept: /”表示客户端声明自己可以接受任何格式的数据
(5)Content-Encoding字段
说明数据的压缩方法,表示服务器返回的数据使用了什么压缩格式
①Content-Encoding: gzip表示服务器返回的数据采用了gzip方式压缩,告知客户端需要用此方式解压
②客户端在请求时,用 Accept-Encoding 字段说明自己可以接受哪些压缩方法
6、说一下 GET 和 POST 的区别?
(1)GET请求
①Get方法:请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。
②GET方法就是安全且幂等的(是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的)
(2)POST
①POST方法:向URI指定的资源提交数据,数据就放在报文的 body 里
②POST方法不是安全也不是幂等的(POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的)
注意:“安全”指请求方法不会破坏服务器的资源;“幂等”指多次执行相同的操作结果都是相同的
7、HTTP的优缺点?
(1)优点
① 简单:HTTP 基本的报文格式是header + body
,头部信息也是key-value
简单文本的形式,易于理解
② 灵活和易于扩展
- HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充
- 工作在最顶层应用层,下层可以随意变化
③ 应用广泛和跨平台:从台式机的浏览器到手机上的各种APP
(2)缺点
① 无状态
- 好处:不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务
- 坏处:服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦(例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息)
注意:解决无状态问题比较简单的方式是Cookie技术
② 明文传输
- 好处:方便阅读,通过浏览器的 F12 控制台或 Wireshark 抓包都可以直接查看,便于调试
- 坏处:信息内容容易被窃取
③ 不安全
- 通信使用明文(不加密),内容可能会被窃听——比如,账号信息容易泄漏,那你号没了
- 不验证通信方的身份,因此有可能遭遇伪装——比如,访问假的淘宝、拼多多,那你钱没了
- 无法证明报文的完整性,所以有可能已遭篡改——比如,网页上植入垃圾广告,视觉污染,眼没了
8、说下 HTTP/1.1 的性能如何?
HTTP协议是基于TCP/IP,并且使用了「请求 - 应答」的通信模式,所以性能的关键就在这两点里
(1)长连接
①HTTP/1.0 性能上的一个很大的问题:每发起一个请求,都要新建一次 TCP 连接,而且是串行请求,做了许多无谓的 TCP 连接建立和断开,增加了通信开销。
②HTTP/1.1 提出了长连接(持久连接)的通信方式;好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载;特点是只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
(2)管道网络传输
长连接使得管道网络传输成为可能
①在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间(举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。管道机制则是允许浏览器同时发出 A 请求和 B 请求)
②服务器按照顺序,先回应 A 请求,完成后再回应 B 请求
(3)队头堵塞
「请求 - 应答」的模式加剧了 HTTP 的性能问题
当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据,这就是「队头阻塞」9、HTTP 与 HTTPS 有哪些区别?
(1)HTTP的信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
(2)HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
(3)HTTP 的端口号是 80,HTTPS 的端口号是 443。
(4)HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。10、HTTPS 解决了 HTTP 的哪些问题?
(1)HTTP 的问题(主要是明文传输)
窃听风险——比如通信链路上可以获取通信内容,用户号容易没。
篡改风险——比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
冒充风险——比如冒充淘宝网站,用户钱容易没。
(2)HTTPS 解决(在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议)
信息加密——交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
校验机制——无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
身份证书——证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。11、HTTPS 是如何解决 HTTP 的问题?
(1)混合加密
——保证信息的机密性,解决了窃听的风险
采用的是对称加密和非对称加密结合的「混合加密」方式:
①在通信建立前采用非对称加密的方式交换「会话秘钥」;
②在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。采用「混合加密」的方式的原因:
- 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换
- 非对称加密使用两个密钥——公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢
(2)摘要算法
——实现完整性,能够为数据生成独一无二的“指纹”,用于校验数据的完整性,解决了篡改的风险
客户端在发送明文之前会通过摘要算法算出明文的「指纹」,发送的时候把「指纹 + 明文」一同加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过比较客户端携带的「指纹」和当前算出的「指纹」做比较,若「指纹」相同,说明数据是完整的。
(3)数字证书
——保证服务器公钥的身份,解决冒充的风险
客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。那么如何保证公钥不被篡改和信任度?这里就需要借助第三方权威机构 CA(数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。
12、HTTPS 是如何建立连接的?其间交互了什么?
(1)SSL/TLS 协议基本流程
①客户端向服务器索要并验证服务器的公钥(建立)
②双方协商生产「会话秘钥」(建立)
③双方采用「会话秘钥」进行加密通信(通信)
(2)SSL/TLS 协议建立的过程
①ClientHello
第一步:由客户端向服务器发起加密通信请求,也就是ClientHello请求
客户端主要向服务器发送以下信息:
- 客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本
- 客户端生产的随机数(Client Random),后面用于生产「会话秘钥」
- 客户端支持的密码套件列表,如 RSA 加密算法
②SeverHello
第二步:服务器收到客户端请求后,向客户端发出响应,也就是SeverHello
服务器响应的内容如下:
- 确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信
- 服务器生产的随机数(Server Random),后面用于生产「会话秘钥」
- 确认的密码套件列表,如 RSA 加密算法
- 服务器的数字证书
③客户端回应
第三步:客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文
向服务器发送如下信息:
- 一个随机数(pre-master key),该随机数会被服务器公钥加密
- 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务器校验
注:上面第一项的随机数是整个握手阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。
④服务器的最后回应
第四步:服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」
向客户端发生最后的信息:
- 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验
(3)加密通信过程
SSL/TLS 的握手阶段全部结束后,客户端与服务器进入加密通信,使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。
13、说说 HTTP/1.1 相比 HTTP/1.0 提高了什么性能?
(1)提高的性能
①使用 TCP 长连接的方式改善了 HTTP/1.0 短连接造成的性能开销
②支持管道(pipeline)网络传输,减少整体的响应时间
(2)HTTP/1.1 的性能瓶颈
①请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分;
②发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
③服务器是按请求的顺序响应的,如果服务器响应慢,会导致客户端一直请求不到数据,即队头阻塞;
④没有请求优先级控制;
⑤请求只能从客户端开始,服务器只能被动响应
14、HTTP/2 相比 HTTP/1.1 做了什么优化?
https://xiaolincoding.com/network/2_http/http2.html
(1)头部压缩
HTTP/2 会压缩请求/响应头(Header),同时发出多个请求(它们头部一样或类似),那么协议会消除重复的部分。
HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
(2)二进制格式
头信息和数据体都是二进制格式,这样计算机收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率。
(3)数据流
① HTTP/2 的数据包不是按顺序发送的
②每个请求或回应的所有数据包,称为一个数据流
③每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数
④客户端可以指定数据流的优先级,优先级高的请求,服务器就先响应该请求
(4)多路复用
① HTTP/2 是可以在一个连接中并发多个请求或回应
② HTTP/2 移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率
(5)服务器推送
服务不再是被动地响应,也可以主动向客户端发送消息
15、HTTP/2 有哪些缺陷?HTTP/3 做了哪些优化?
https://xiaolincoding.com/network/2_http/http3.html
(1)HTTP/2 主要问题
多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。
(2)优化
①UDP发生是不管顺序,也不管丢包的
②UDP是不可靠传输的,但基于UDP的QUIC协议可以实现类似TCP的可靠性传输。
③QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响。
④TLS3 升级成了最新的 1.3 版本,头部压缩算法也升级成了 QPack
⑤QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数
16、HTTP/1.1如何优化?
(1)使用 KeepAlive 将 HTTP 从短连接改成长连接(通过减少 TCP 连接建立和断开的次数,来减少了网络传输的延迟,从而提高 HTTP/1.1 协议的传输效率)
(2)尽量避免发送 HTTP 请求
通过缓存技术来避免发送 HTTP 请求。客户端收到第一个请求的响应后,可以将其缓存在本地磁盘,下次请求的时候,如果缓存没过期,就直接读取本地缓存的响应数据;如果缓存过期,客户端发送请求的时候带上响应数据的摘要,服务器比对后发现资源没有变化,就发出不带包体的 304 响应,告诉客户端缓存的响应仍然有效。
(3)在需要发送 HTTP 请求时,考虑如何减少请求次数
①将原本由客户端处理的重定向请求,交给代理服务器处理;
②将多个小资源合并成一个大资源再传输,能够减少 HTTP 请求次数以及头部的重复传输,再来减少 TCP 连接数量,进而省去 TCP 握手和慢启动的网络消耗;
③按需访问资源,只访问当前用户看得到/用得到的资源,以此达到延迟请求
(4)减少服务器的 HTTP 响应的数据大小
通过压缩响应资源,降低传输资源的大小,从而提高传输效率
17、如何避免发送 HTTP 请求?
(1)概述
①对于一些重复的 HTTP 请求,可以把这对「请求-响应」的数据都缓存在本地,那么下次就直接读取本地的数据,不必在通过网络获取服务器的响应
②避免发送 HTTP 请求的方法就是通过缓存技术
(2)缓存如何做到
①客户端会把第一次请求以及响应的数据保存在本地磁盘上,其中将请求的 URL 作为 key,而响应作为 value,两者形成映射关系
②当后续发起相同的请求时,就可以先在本地磁盘上通过 key 查到对应的 value,也就是响应,如果找到了,就直接从本地读取该响应
(3)缓存的响应不是最新的,而客户端并不知情,那么该怎么办呢?
①服务器在发送 HTTP 响应时,会估算一个过期的时间,并把这个信息放到响应头部中
②客户端在查看响应头部的信息时,一旦发现缓存的响应是过期的,则就会重新发送网络请求
③客户端在重新发送请求时,在请求的Etag
头部带上第一次请求的响应头部中的摘要,这个摘要是唯一标识响应的资源,当服务器收到请求后,会将本地资源的摘要与请求中的摘要做个比较:
- 如果不同,那么说明客户端的缓存已经没有价值,服务器在响应中带上最新的资源
如果相同,说明客户端的缓存还是可以继续使用的,那么服务器仅返回不含有包体的
304 Not Modified
响应,告诉客户端仍然有效,这样就可以减少响应资源在网络中传输的延时18、如何减少 HTTP 请求次数?
(1)减少重定向请求次数
①重定向请求:服务器上的一个资源可能由于迁移、维护等原因从 url1 移至 url2 后,而客户端不知情,它还是继续请求 url1,这时服务器不能粗暴地返回错误,而是通过 302 响应码和 Location 头部,告诉客户端该资源已经迁移至 url2 了,于是客户端需要再发送 url2 请求以获得服务器的资源
②如果重定向请求越多,那么客户端就要多次发起 HTTP 请求,每一次的 HTTP 请求都得经过网络,这无疑会越降低网络性能
③服务端这一方往往不只有一台服务器,比如源服务器上一级是代理服务器,然后代理服务器才与客户端通信,这时客户端重定向就会导致客户端与代理服务器之间需要 2 次消息传递
④如果重定向的工作交由代理服务器完成,就能减少 HTTP 请求次数
(2)合并请求
①如果把多个访问小文件的请求合并成一个大的请求,可以减少请求次数,也就意味着减少了重复发送的 HTTP 头部
②如果合并了请求,就会减少TCP连接的数量,也就节省TCP握手和慢启动过程耗费的时间
③合并请求的方式就是合并资源,以一个大资源的请求替换多个小资源的请求
④问题:当大资源中的某一个小资源发生变化后,客户端必须重新下载整个完整的大资源文件,这会带来额外的网络消耗
(3)延迟发送请求
请求网页时,没必要把全部资源都获取到,而是只获取当前用户所看到的页面资源,根据用户的操作获取需要的资源即可,从而达到延迟发送请求的效果。19、如何减少 HTTP 响应的数据大小?
对于 HTTP 的请求和响应,通常 HTTP 的响应的数据大小会比较大,即服务器返回的资源会比较大。于是,我们可以考虑对响应的资源进行压缩,这样就可以减少响应的数据大小,从而提高网络传输的效率。
(1)无损压缩
①定义:指资源经过压缩后,信息不被破坏,还能完全恢复到压缩前的原样
②场景:适用在文本文件、程序可执行文件、程序源代码
③过程:首先,针对代码的语法规则进行压缩,去掉多余的符号(如空格、换行符等);接着就是无损压缩,对原始资源建立统计模型,利用这个统计模型,将常出现的数据用较短的二进制比特序列表示,将不常出现的数据用较长的二进制比特序列表示,生成二进制比特序列一般是「霍夫曼编码」算法
④常见的无损压缩:gzip
(2)有损压缩
①定义:解压的数据会与原始数据不同但是非常接近(主要将次要的数据舍弃,牺牲一些质量来减少数据量、提高压缩比)
②场景:常用于压缩多媒体数据,比如音频、视频、图片等
③达到比较高压缩比:Google 推出的 WebP 格式20、HTTPS 如何优化?
产生性能损耗主要有两个方面:一是TLS 协议握手过程,二是握手后的对称加密报文传输。
(1)硬件优化
①一个好的CPU可以提高计算性能,因为 HTTPS 连接过程中就有大量需要计算密钥的过程,所以这样可以加速 TLS 握手过程
②选择可以支持AES-NI特性的CPU,因为这种款式的 CPU 能在指令级别优化了 AES 算法,这样便加速了数据的加解密传输过程
(2)软件优化
主要是软件升级,将正在使用的软件升级到最新版本,因为最新版本不仅提供了最新的特性,也优化了以前软件的问题或性能(对于公司而言,实行软件升级,会花费时间和人力,同时也存在一定的风险,也可能会影响正常的线上服务)
(3)协议优化
对「密钥交换过程」进行优化
①密钥交换算法优化TLS 1.2 版本如果使用的是 RSA 密钥交换算法,那么需要 4 次握手,也就是要花费 2 RTT,才可以进行应用数据的传输,而且 RSA 密钥交换算法不具备前向安全性。总之使用 RSA 密钥交换算法的 TLS 握手过程,不仅慢,而且安全性也不高。
- 尽量选用ECDHE密钥交换算法,客户端可以在 TLS 协议的第 3 次握手后,第 4 次握手前,发送加密的应用数据,以此将 TLS 握手的消息往返由 2 RTT 减少到 1 RTT,而且安全性也高,具备前向安全性。
②TLS 升级
直接把 TLS 1.2 升级成 TLS 1.3,TLS 1.3 大幅度简化了握手的步骤,完成 TLS 握手只要 1 RTT,而且安全性更高。
(4)证书优化
为了验证的服务器的身份,服务器会在 TSL 握手过程中,把自己的证书发给客户端,以此证明自己身份是可信的。
①证书传输优化
- 让证书便于传输,那必须减小证书的大小。
- 对于服务器的证书应该选择椭圆曲线(ECDSA)证书,而不是 RSA 证书,因为在相同安全强度下, ECC 密钥长度比 RSA 短的多。
②证书验证优化
- CRL
定义:CRL称为证书吊销列表(Certificate Revocation List),由 CA 定期更新,列表内容都是被撤销信任的证书序号。如果服务器的证书在此列表,就认为证书已经失效,不在的话,则认为证书是有效的。
存在的问题:实时性差;随着吊销证书的增多,列表会越来越大,下载的速度就会越慢
- OCSP
定义:OCSP称为在线证书状态协议(Online Certificate Status Protocol),工作方式是向 CA 发送查询请求,让 CA 返回证书的有效状态。现在基本都是使用OCSP来查询证书的有效性
存在的问题:OCSP需要向CA查询,因此要发生网络请求,如果网络状态不好或者CA服务器繁忙,也会导致客户端在校验证书这一环节的延时变大
- OCSP Stapling
解决OCSP存在的问题
原理:服务器向 CA 周期性地查询证书状态,获得一个带有时间戳和签名的响应结果并缓存它。当有客户端发起连接请求时,服务器会把这个「响应结果」在 TLS 握手过程中发给客户端。由于有签名的存在,服务器无法篡改,因此客户端就能得知证书是否已被吊销了,这样客户端就不需要再去查询。
(5)会话复用
TLS 握手的目的就是为了协商出会话密钥,即对称加密密钥,如果我们把首次 TLS 握手协商的对称加密密钥缓存起来,待下次需要建立 HTTPS 连接时,直接「复用」这个密钥,就减少 TLS 握手的性能损耗
① Session ID
工作原理:客户端和服务器首次 TLS 握手连接后,双方会在内存缓存会话密钥,并用唯一的 Session ID 来标识,Session ID 和会话密钥相当于 key-value 的关系。
- 当客户端再次连接时,消息里会带上 Session ID,服务器收到后就会从内存找,如果找到就直接用该会话密钥恢复会话状态,跳过其余的过程,只用一个消息往返就可以建立安全通信。当然为了安全性,内存中的会话密钥会定期失效。
缺点:
② Session Ticket
工作原理:服务器不再缓存每个客户端的会话密钥,而是把缓存的工作交给了客户端
- 客户端与服务器首次建立连接时,服务器会加密「会话密钥」作为 Ticket 发给客户端,交给客户端缓存该 Ticket。
- 客户端再次连接服务器时,客户端会发送 Ticket,服务器解密后就可以获取上一次的会话密钥,然后验证有效期,如果没问题,就可以恢复会话了,开始加密通信。
- 对于集群服务器的话,要确保每台服务器加密 「会话密钥」的密钥是一致的,这样客户端携带 Ticket 访问任意一台服务器时,都能恢复会话。
③ Pre-shared Key
工作原理:和 Ticket 类似,只不过在重连时,客户端会把 Ticket 和 HTTP 请求一同发送给服务端
说明:Session ID 和 Session Ticket 方式都需要在 1 RTT 才能恢复会话,对于重连 TLS1.3 只需要 0 RTT
三、传输层
1、TCP和UDP的区别?应用场景有哪些?
(1)TCP和UDP的区别
①连接
TCP是面向连接的传输层协议,传输数据前要先建立连接;
UDP是无连接的,即刻传输数据
②服务对象
TCP是⼀对⼀的两点服务,即一条连接只有两个端点;
UDP支持一对一、一对多、多对多的交互通信
③可靠性
TCP是可靠进行数据交付,数据是无差错、不丢失、不重复、按序到达的;
UDP是尽最大努力进行数据交付,不保证数据传输的可靠性
④拥塞控制和流量控制
TCP有拥塞控制和流量控制机制,保证数据传输的安全性;
UDP没有这种机制,即使网络非常拥堵,也不会影响UDP的发送速率
⑤首部开销
TCP首部长度较长,会有一定的开销,首部在没有使用【选项】字段时是20个字节,如果使用了【选项】字段则会变长
UDP首部只有8个字节,并且固定不变,开销较小
⑥传输方式
TCP是流式传输,没有边界,但保证顺序和可靠
UDP是一个包一个包的发送,是有边界的,但可能会丢包和乱序
⑦分片不同
TCP的数据大小如果大于MSS大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装TCP数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
UDP的数据大小如果大于MTU大小,则会在IP层进行分片,目标主机收到后,在IP层组装完数据,再传给传输层,但如果中途丢了一个分片,在实现可靠传输的UDP时就需要重传所有的数据包,这样传输效率非常差,所以通常UDP的报文应该小于MTU。
(2)应用场景
TCP(面向连接,可靠传输)
- FTP文件传输
- HTTP / HTTPS
UDP(面向无连接,随时发送数据,处理简单高效)
- 包总量较少的通信,比如DNS、SNMP等
- 视频、音频等多媒体通信
-
2、TCP的头部格式
(1)序列号
在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
(2)确认应答号
指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。
(3)控制位 ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1
- RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接
- SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
- FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
3、为什么需要 TCP 协议?TCP 工作在哪一层?
(1)为什么需要TCP协议
① IP 层是「不可靠」的,它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据的完整性。
② 如果需要保障网络数据包的可靠性,那么就需要由上层(传输层)的 TCP 协议来负责。
(2)TCP工作的层次
TCP 是一个工作在传输层的可靠数据传输的服务,它能确保接收端接收的网络包是无损坏、无间隔、非冗余和按序的。4、什么是 TCP ?
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。
(1)面向连接
一定是一对一才能建立连接,不能一对多
(2)可靠
无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能从发送端到达接收端
(3)基于字节流
①消息是「没有边界」的,所以无论我们消息有多大都可以进行传输;
②消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节,那么也不能扔给应用层去处理
③对「重复」的报文会自动丢弃5、什么是 TCP 连接?
(1)定义
用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小
(2)说明
建立一个 TCP 连接是需要客户端与服务器端达成上述三个信息的共识
① Socket:由 IP 地址和端口号组成
② 序列号:用来解决乱序问题等
③ 窗口大小:用来做流量控制6、如何唯一确定一个 TCP 连接呢?
TCP 四元组可以唯一的确定一个连接,这个四元组包括源地址、源端口、目的地址、目的端口
(1)地址
源地址和目的地址的字段(32位)是在 IP 头部中,作用是通过 IP 协议发送报文给对方主机。
(2)端口
源端口和目的端口的字段(16位)是在 TCP 头部中,作用是告诉 TCP 协议应该把报文发给哪个进程。7、有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是多少?
(1)说明
服务器通常固定在某个本地端口上监听,等待客户端的连接请求。
(2)计算公式
客户端 IP 和端口是可变的,则理论值的计算公式如下:
对 IPv4,客户端的 IP 数最多为 2 的 32 次方,客户端的端口数最多为 2 的 16 次方,也就是服务端单机最大 TCP 连接数,约为 2 的 48 次方。
(3)注意
服务端最大并发 TCP 连接数远不能达到理论上限,会受如下因素影响:
①文件描述符限制
每个 TCP 连接都是一个文件,如果文件描述符被占满了,会发生 too many open files
②内存限制
每个 TCP 连接都要占用一定内存,操作系统的内存是有限的,如果内存资源被占满后,会发生 OOM(Out of Memory)8、UDP头部格式
目标和源端口:主要是告诉 UDP 协议应该把报文发给哪个进程。
包长度:保存了 UDP 首部的长度跟数据的长度之和,首部固定是8个字节。
校验和:提供可靠的 UDP 首部和数据而设计,防止收到在网络传输中受损的 UDP包9、TCP 三次握手过程
(1)一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态
(2)客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1 ,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态。
(3)服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。
(4)客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于 ESTABLISHED 状态。
(5)服务器收到客户端的应答报文后,也进入 ESTABLISHED 状态。
(6)一旦完成三次握手,双方都处于 ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了。第三次握手是可以携带数据的,前两次握手是不可以携带数据的
10、为什么TCP是三次握手?不是两次、四次?
(1)为什么是三次握手
① 阻止重复历史连接的初始化(主要原因)
客户端连续发送多次 SYN 建立连接的报文,在网络拥堵情况下:
- 一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端,那么此时服务端就会回一个 SYN + ACK 报文给客户端;
- 客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时),那么客户端就会发送 RST 报文给服务端,表示中止这一次连接。
② 同步双方初始序列号
- TCP 协议的通信双方, 都必须维护一个「序列号」, 序列号是可靠传输的一个关键因素,它的作用:接收方可以去除重复的数据;接收方可以根据数据包的序列号按序接收;可以标识发送出去的数据包中, 哪些是已经被对方收到的(通过 ACK 报文中的序列号知道)。
- 当客户端发送携带「初始序列号」的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。
③ 避免资源浪费
如果是两次握手,当客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。
(2)为什么TCP两次握手为什么无法阻止历史连接呢?
在两次握手的情况下,「被动发起方」没有中间状态给「主动发起方」来阻止历史连接,导致「被动发起方」可能建立一个历史连接,造成资源浪费。
(3)两次握手与四次握手对同步双方初始序列号的影响
①四次握手能够可靠的同步双方的初始化序号
②两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收
(4)不使用「两次握手」和「四次握手」的原因
①两次握手:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
②四次握手:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。
11、为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢?
(1)防止历史报文被下一个相同四元组的连接接收(主要原因)
(2)安全性,防止黑客伪造的相同序列号的 TCP 报文被对方接收
12、初始序列号 ISN 是如何随机产生的?
起始 ISN 是基于时钟的,每 4 微秒 + 1,转一圈要 4.55 个小时。
初始化序列号 ISN 随机生成算法:ISN = M + F(localhost, localport, remotehost, remoteport)
- M 是一个计时器,这个计时器每隔 4 微秒加 1;
F 是一个 Hash 算法,根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。
13、既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢?
(1)MTU和MSS
①MTU
:一个网络包的最大长度,以太网中一般为 1500 字节;
②MSS
:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度
(2)如果将 TCP 的整个报文(头部 + 数据)交给 IP 层进行分片,会有什么异常呢?
①当 IP 层有一个超过 MTU 大小的数据(TCP 头部 + TCP 数据)要发送,那么 IP 层就要进行分片,把数据分片成若干片,保证每一个分片都小于 MTU。把一份 IP 数据报进行分片以后,由目标主机的 IP 层来进行重新组装后,再交给上一层 TCP 传输层。
②这存在隐患的,那么当如果一个 IP 分片丢失,整个 IP 报文的所有分片都得重传。
③因为 IP 层本身没有超时重传机制,它由传输层的 TCP 来负责超时和重传。
④当接收方发现 TCP 报文(头部 + 数据)的某一片丢失后,则不会响应 ACK 给对方,那么发送方的 TCP 在超时后,就会重发「整个 TCP 报文(头部 + 数据)」。
⑤由 IP 层进行分片传输,是非常没有效率的
(3)TCP层为什么需要MSS
①为了达到最佳的传输效能 TCP 协议在建立连接的时候通常要协商双方的 MSS 值,当 TCP 层发现数据超过 MSS 时,则就先会进行分片,当然由它形成的 IP 包的长度也就不会大于 MTU ,自然也就不用 IP 分片了。
②经过 TCP 层分片后,如果一个 TCP 分片丢失后,进行重发时也是以 MSS 为单位,而不用重传所有的分片,大大增加了重传的效率。14、第一次握手丢失了,会发生什么?
(1)当客户端想和服务端建立 TCP 连接的时候,首先第一个发的就是 SYN 报文,然后进入到 SYN_SENT 状态。在这之后,如果客户端迟迟收不到服务端的 SYN-ACK 报文(第二次握手),就会触发「超时重传」机制,重传 SYN 报文。
(2)通常,每次超时的时间是上一次的 2 倍。第一次超时重传是在 1 秒后,第二次超时重传是在 2 秒,第三次超时重传是在 4 秒后,第四次超时重传是在 8 秒后,第五次是在超时重传 16 秒后。当第五次超时重传后,会继续等待 32 秒,如果服务端仍然没有回应 ACK,客户端就不再发送 SYN 包,然后断开 TCP 连接。15、第二次握手丢失了,会发生什么?
(1)当服务端收到客户端的第一次握手后,就会回 SYN-ACK 报文给客户端,此时服务端会进入 SYN_RCVD 状态(第二次握手)
(2)第二次握手的SYN-ACK
报文目的
①第二次握手里的 ACK,是对第一次握手的确认报文;
②第二次握手里的 SYN,是服务端发起建立 TCP 连接的报文;
(3)第二次握手丢失
①如果客户端迟迟没有收到第二次握手,那么客户端就觉得可能自己的 SYN 报文(第一次握手)丢失了,于是客户端就会触发超时重传机制,重传 SYN 报文
②如果第二次握手丢失了,服务端就收不到第三次握手,于是服务端这边会触发超时重传机制,重传 SYN-ACK 报文16、第三次握手丢失了,会发生什么?
(1)客户端收到服务端的 SYN-ACK 报文后,就会给服务端回一个 ACK 报文,也就是第三次握手,此时客户端状态进入到 ESTABLISH 状态。
(2)如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手,或者达到最大重传次数。
(3)ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文。17、什么是 SYN 攻击?如何避免 SYN 攻击?
(1)SYN攻击
假设攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的半连接队列,使得服务器不能为正常用户服务。
(2)避免SYN攻击
①修改 Linux 内核参数,控制队列大小和当队列满时应做什么处理
②tcp_syncookies
方式:当 「 SYN 队列」满之后,后续服务器收到 SYN 包,不进入「 SYN 队列」;计算出一个 cookie 值,再以 SYN + ACK 中的「序列号」返回客户端,服务端接收到客户端的应答报文时,服务器会检查这个 ACK 包的合法性。如果合法,直接放入到「 Accept 队列」;最后应用通过调用 accpet() socket 接口,从「 Accept 队列」取出的连接。18、TCP的四次挥手?
客户端或服务端都可以主动断开连接,断开连接后主机中的「资源」将被释放
(1)客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
(2)服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。
(3)客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
(4)等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
(5)客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态。
(6)服务器收到了 ACK 应答报文后,就进入了 CLOSED 状态,至此服务端已经完成连接的关闭。
(7)客户端在经过 2MSL 一段时间后,自动进入 CLOSED 状态,至此客户端也完成连接的关闭。19、为什么挥手需要四次?
(1)发 FIN 包的过程
①关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
②服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
(2)挥手需要四次
服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次。20、第一次挥手丢失了,会发生什么?
(1)正常情况
当客户端(主动关闭方)调用 close 函数后,就会向服务端发送 FIN 报文,试图与服务端断开连接,此时客户端的连接进入到 FIN_WAIT_1 状态。正常情况下,如果能及时收到服务端(被动关闭方)的 ACK,则会很快变为 FIN_WAIT2状态。
(2)第一次挥手丢失
客户端迟迟收不到被动方的 ACK 的话,会触发超时重传机制,重传 FIN 报文,重发次数由tcp_orphan_retries 参数控制。当客户端重传 FIN 报文的次数超过 tcp_orphan_retries 后,就不再发送 FIN 报文,直接进入到 close 状态。21、第二次挥手丢失了,会发生什么?
(1)正常情况
当服务端收到客户端的第一次挥手后,就会先回一个 ACK 确认报文,此时服务端的连接进入到 CLOSE_WAIT 状态(ACK 报文是不会重传的)
(2)第二次挥手丢失
客户端就会触发超时重传机制,重传 FIN 报文,直到收到服务端的第二次挥手,或者达到最大的重传次数。22、第三次挥手丢失了,会发生什么?
(1)正常情况
服务端处于 CLOSE_WAIT 状态时,调用了 close 函数,内核就会发出 FIN 报文,同时连接进入 LAST_ACK 状态,等待客户端返回 ACK 来确认连接关闭。
(2)第三次挥手丢失
如果迟迟收不到这个 ACK,服务端就会重发 FIN 报文,重发次数仍然由 tcp_orphan_retries 参数控制,这与客户端重发 FIN 报文的重传次数控制方式是一样的。23、第四次挥手丢失了,会发生什么?
(1)正常情况
当客户端收到服务端的第三次挥手的 FIN 报文后,就会回 ACK 报文,此时客户端连接进入 TIME_WAIT 状态。在 Linux 中,TIME_WAIT 状态会持续 2MSL 后才会进入关闭状态。服务端(被动关闭方)没有收到 ACK 报文前,还是处于 LAST_ACK 状态。
(2)第四次挥手丢失
如果第四次挥手的 ACK 报文没有到达服务端,服务端就会重发 FIN 报文,重发次数仍然由前面介绍过的 tcp_orphan_retries 参数控制。24、为什么 TIME_WAIT 等待的时间是 2MSL?
(1)什么是MSL
指报文最大生存时间,是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
(2)MSL与TTL的区别
①说明TCP 报文基于是 IP 协议的,而 IP 头中有一个 TTL 字段,是 IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机。
- TTL 的值一般是 64,Linux 将 MSL 设置为 30 秒,意味着 Linux 认为数据报文经过 64 个路由器的时间不会超过 30 秒,如果超过了,就认为报文已经消失在网络中了。
②区别:MSL 的单位是时间,TTL 是经过路由跳数。MSL 应该要大于等于 TTL 消耗为 0 的时间,以确保报文已被自然消亡。
(3)为什么等待2MSL
①怕被动关闭方没有收到最后的 ACK
②假设立马断开连接,但是又重用了这个连接,就是四元组完全一致,并且序号还在合适的范围内,那么新的连接有可能会被已关闭连接链路上的一些残留数据干扰,因此给予一定的时间来处理一些残留数据。
25、为什么需要 TIME_WAIT 状态?
(1)说明
主动发起关闭连接的一方,才会有 TIME-WAIT 状态。
(2)原因
①防止历史连接中的数据,被后面相同四元组的连接错误的接收
②保证「被动关闭连接」的一方,能被正确的关闭(等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭)
26、TIME_WAIT 过多有什么危害?
(1)内存资源占用
(2)对端口资源的占用,一个 TCP 连接至少消耗「发起连接方」的一个本地端口——如果「发起连接方」的 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接。
27、如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP 有一个机制是保活机制:
定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。
28、如果已经建立了连接,但是客户端的进程崩溃会发生什么?
29、针对 TCP 应该如何 Socket 编程?
(1)步骤
①服务端和客户端初始化 socket,得到文件描述符;
②服务端调用 bind,将绑定在 IP 地址和端口;
③服务端调用 listen,进行监听;
④服务端调用 accept,等待客户端连接;
⑤客户端调用 connect,向服务器端的地址和端口发起连接请求;
⑥服务端 accept 返回用于传输的 socket 的文件描述符;
⑦客户端调用 write 写入数据;服务端调用 read 读取数据;
⑧客户端断开连接时,会调用 close,那么服务端 read 读取数据的时候,就会读取到了 EOF,待处理完数据后,服务端调用 close,表示连接关闭。
(2)说明
①服务端调用 accept 时,连接成功了会返回一个已完成连接的 socket,后续用来传输数据
②监听的 socket 和真正用来传送数据的 socket,是「两个」 socket,一个叫作监听 socket,一个叫作已完成连接 socket。
30、accept 发生在三次握手的哪一步?
(1)客户端连接服务端时发送了什么?
①客户端的协议栈向服务器端发送了 SYN 包,并告诉服务器端当前发送序列号 client_isn,客户端进入 SYN_SENT 状态;
②服务器端的协议栈收到这个包之后,和客户端进行 ACK 应答,应答的值为 client_isn+1,表示对 SYN 包 client_isn 的确认,同时服务器也发送一个 SYN 包,告诉客户端当前我的发送序列号为 server_isn,服务器端进入 SYN_RCVD 状态;
③客户端协议栈收到 ACK 之后,使得应用程序从 connect 调用返回,表示客户端到服务器端的单向连接建立成功,客户端的状态为 ESTABLISHED,同时客户端协议栈也会对服务器端的 SYN 包进行应答,应答数据为 server_isn+1;
④应答包到达服务器端后,服务器端协议栈使得 accept 阻塞调用返回,这个时候服务器端到客户端的单向连接也建立成功,服务器端也进入 ESTABLISHED 状态。
(2)accept 发生在三次握手的哪一步
客户端 connect 成功返回是在第二次握手,服务端 accept 成功返回是在三次握手成功之后。
31、客户端调用 close 了,连接是断开的流程是什么?
①客户端调用 close,表明客户端没有数据需要发送了,则此时会向服务端发送 FIN 报文,进入 FIN_WAIT_1 状态;
②服务端接收到了 FIN 报文,TCP 协议栈会为 FIN 包插入一个文件结束符 EOF 到接收缓冲区中,应用程序可以通过 read 调用来感知这个 FIN 包。这个 EOF 会被放在已排队等候的其他已接收的数据之后,这就意味着服务端需要处理这种异常情况,因为 EOF 表示在该连接上再无额外数据到达。此时,服务端进入 CLOSE_WAIT 状态;
③当服务端处理完数据后,自然就会读到 EOF,于是也调用 close 关闭它的套接字,这会使得服务端发出一个 FIN 包,之后处于 LAST_ACK 状态;
④客户端接收到服务端的 FIN 包,并发送 ACK 确认包给服务端,此时客户端将进入 TIME_WAIT 状态;
⑤服务端收到 ACK 确认包后,就进入了最后的 CLOSE 状态;
⑥客户端经过 2MSL 时间之后,也进入 CLOSE 状态。
32、TCP 是面向连接的,那么连接是什么?
连接是双方都维护了一个状态,通过每一次通信来维护状态的变更。
3、为什么要等待2MSL的时间才关闭?
(1)保证连接的可靠关闭。
(2)避免端口重用带来的数据混淆:如果client直接进入CLOSED状态,又用相同端口号向server建立一个连接,上一次连接的部分数据在网络中延迟到达server,数据就可能发生混淆了。
4、TCP怎么保证传输过程的可靠性?
(1)校验和:发送方在发送数据之前计算校验和,接收方收到数据后同样计算,如果不一致,那么传输有误。
(2)确认应答,序列号:TCP进行传输时数据都进行了编号,每次接收方返回ACK都有确认序列号。
(3)超时重传:如果发送方发送数据一段时间后没有收到ACK,那么就重发数据。
(4)连接管理:三次握手和四次挥手的过程。
(5)流量控制:TCP协议报头包含16位的窗口大小,接收方会在返回ACK时同时把自己的即时窗口填入,发送方就根据报文中窗口的大小控制发送速度。
(6)拥塞控制:刚开始发送数据的时候,拥塞窗口是1,以后每次收到ACK,则拥塞窗口+1,然后将拥塞窗口和收到的窗口取较小值作为实际发送的窗口,如果发生超时重传,拥塞窗口重置为1——这样做的目的就是为了保证传输过程的高效性和可靠性。
5、知道HTTPS的工作原理吗?
(1)用户通过浏览器请求https网站,服务器收到请求,选择浏览器支持的加密和hash算法,同时返回数字证书给浏览器,包含颁发机构、网址、公钥、证书有效期等信息。
(2)浏览器对证书的内容进行校验,如果有问题,则会有一个提示警告。否则,就生成一个随机数X,同时使用证书中的公钥进行加密,并且发送给服务器。
(3)服务器收到之后,使用私钥解密,得到随机数X,然后使用X对网页内容进行加密,返回给浏览器
(4)浏览器则使用X和之前约定的加密算法进行解密,得到最终的网页内容
6、负载均衡有哪些实现方式?
(1)DNS:一般用于实现地理级别的负载均衡,不同地域的用户通过DNS的解析可以返回不同的IP地址(扩展性太差,控制权在域名服务商)
(2)HTTP重定向:通过修改Http响应头的Location(对性能有影响,而且增加请求耗时)
(3)反向代理:作用于应用层的模式,常见的有Nginx(部署简单,成本低,容易扩展)
(4)IP:作用于网络层的和传输层的模式,通过对数据包的IP地址和端口进行修改来达到负载均衡的效果,常见的有LVS
7、TCP如何保证可靠性
(1)TCP的连接是基于三次握手,而断开则是四次挥手,确保连接和断开的可靠性。
(2)体现在有状态:TCP会记录哪些数据发送了,哪些数据被接受了,哪些没有被接受,并且保证数据包按序到达,保证数据传输不出差错。
(3)体现在可控制。它有报文校验、ACK应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制。
8、怎么理解同步和阻塞?
可以把IO操作理解为两个部分:发起IO请求、实际的IO读写操作
(1)同步和异步在于第二个,实际的IO读写操作,如果操作系统帮你完成了再通知你,那就是异步,否则都叫做同步。
(2)阻塞和非阻塞在于第一个,发起IO请求,对于NIO来说通过channel发起IO操作请求后,其实就返回了,所以是非阻塞。
9、谈一下你对Reactor模型的理解?
(1)组成
Reactor:负责查询、响应IO事件,当检测到IO事件时,分发给Handler处理。
Handler:与IO事件绑定,负责IO事件的处理。
(2)实现方式
①单线程Reactor
reactor和handler在一个线程中,如果某个handler阻塞的话,会导致其他所有的handler无法执行,而且无法充分利用多核的性能。
②单Reactor多线程
充分发挥多核的特性,同时把非IO的操作剥离开。单个Reactor承担了所有的事件监听、响应工作,如果连接过多,还是可能存在性能问题。
③多Reactor多线程
mainReactor建立连接,多个subReactor则负责数据读写。