计算机网络面试题
2022-10-28 / 可可西里

计算机网络常见面试题

1. OSI七层模型,TCP/IP四层模型,五层协议

69.jpg
1.1 OSI七层模型
1.jpeg
1.2 TCP/IP四层模型
  • 它只有四层,相当于五层协议中数据链路层和物理层合并为网络接口层
  • 现在的 TCP/IP 体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者网络接口层
  • TCP/IP 协议族是一种沙漏形状,中间小两边大,IP 协议在其中占用举足轻重的地位
image.png
1.3 五层协议
  • 应用层: 提供用户接口,特指能够发起网络流量的程序,比如客户端程序:QQ,MSN,浏览器等;服务器程序:web服务器,邮件服务器,流媒体服务器等等。数据单位为报文
  • 传输层: 提供的是进程间的通用数据传输服务。由于应用层协议很多,定义通用的运输层协议就可以支持不断增多的应用层协议
  • 网络层: 为主机间提供数据传输服务,而运输层协议是为主机中的进程提供服务。网络层把运输层传递下来的报文段或者用户数据报封装成分组
  • 数据链路层: 不同的网络类型,发送数据的机制不同,数据链路层就是将数据包封装成能够在不同的网络传输的帧。能够进行差错检验,但不纠错,监测处错误丢掉该帧
  • 物理层: 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的主要任务描述为:确定与传输媒体的接口的一些特性

2. TCP和UDP有什么区别

  • TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
  • TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付.
  • TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
  • 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
  • TCP首部开销20字节;UDP的首部开销小,只有8个字节
  • TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

TCP使用场景:

  • 相对于 UDP,TCP 实现了数据传输过程中的各种控制,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。在对可靠性要求较高的情况下,可以使用 TCP,即不考虑 UDP 的时候,都可以选择 TCP

UDP使用场景:

  • 包总量较小的通信(DNS、SNMP)
  • 视频、音频等多媒体通信(即时通信)
  • 广播通信

3. TCP中三次握手和四次挥手

3.1 三次握手
75.jpg

假设 A 为客户端,B 为服务器端:

  • 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求
  • A 向 B 发送连接请求报文段,SYN=1ACK=0,选择一个初始的序号 seq = x
  • B 收到连接请求报文段,如果同意建立连接,则向 A 发送连接确认报文段,SYN=1ACK=1,确认号为 x+1,同时也选择一个初始的序号 seq = y
  • A 收到 B 的连接确认报文段后,还要向 B 发出确认,确认号为 ack = y+1,序号为 seq = x+1
  • A 的 TCP 通知上层应用进程,连接已经建立。
  • B 收到 A 的确认后,连接建立。
  • B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立

为什么TCP连接需要三次握手,两次不可以吗?

  • TCP是一个双向通信协议,通信双方都有能力发送信息,并接收响应。如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
  • 为了防止已失效的连接请求报文段突然又传送到了服务端,占用服务器资源
    • 现假定出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是在某些网络节点长时间滞留了,以致延误到连接释放以后的某个时间才到B。本来这是一个已失效的报文段。但是B收到此失效的连接请求报文段后,就误认为是A有发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了
    • 由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并一直等待A发来数据。B的许多资源就这样白白浪费了
    • 采用三次握手的办法可以防止上述现象的发生。例如在刚才的情况下,A不会向B的确认发出确认。B由于收不到确认,就知道A并没有要求建立连接
3.2 四次挥手
76.jpg

数据传输结束后,通信的双方都可释放连接。现在 A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP连接

  • A 把连接释放报文段首部的 FIN = 1,其序号 seq = u,等待 B 的确认。
  • B 发出确认,确认号 ack = u+1,而这个报文段自己的序号 seq = v。(TCP 服务器进程通知高层应用进程)
  • 从 A 到 B 这个方向的连接就释放了,TCP 连接处于半关闭状态。A 不能向 B 发送数据;B 若发送数据,A 仍要接收
  • 当 B 不再需要连接时,发送连接释放请求报文段,FIN=1。
  • A 收到后发出确认,进入TIME-WAIT状态,等待 2 MSL(2*2 = 4 mins)时间后释放连接。
  • B 收到 A 的确认后释放连接

为什么需要四次挥手

  • 客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT状态
  • 这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文

4. 常见的HTTP状态码有哪些

状态码 类别 原因短语
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错
  • 1XX:
    • 100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应
  • 2XX:
    • 200 OK
    • 204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用
    • 206 Partial Content :表示客户端进行了范围请求。响应报文包含由 Content-Range 指定范围的实体内容
  • 3XX:
    • 301 Moved Permanently :永久性重定向
    • 302 Found :临时性重定向
    • 注:虽然 HTTP 协议规定 301、302 状态下重定向时不允许把 POST 方法改成 GET 方法,但是大多数浏览器都会在 301、302 和 303 状态下的重定向把 POST 方法改成 GET 方法
    • 303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源
    • 304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码
    • 307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法
  • 4XX:
    • 400 Bad Request :请求报文中存在语法错误
    • 401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败
    • 403 Forbidden :请求被拒绝,服务器端没有必要给出拒绝的详细理由
    • 404 Not Found
  • 5XX:
    • 500 Internal Server Error :服务器正在执行请求时发生错误
    • 502 Bad Gateway : 是用来表示代理或网关在处理请求时发生了错误,并不一定是原始服务器出现了问题
    • 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求
    • 504 Gateway Timeout:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应

注意:某些代理服务器在DNS查询超时时会返回400或者500错误

5. HTTPS和HTTP有什么区别

http协议和https协议的区别:传输信息安全性不同连接方式不同端口不同证书专申请方式不同

  • 传输信息安全性不同
    • http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息
    • https协议:是具有安全性的SSL/TLS加密传输协议,为浏览器和服务器之间的通信加密,确保数据传输的安全性
  • 连接方式不同
    • http协议:http的连接很简单,是无状态的,客户端和服务器端都无法验证对方的身份
    • https协议:是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议。客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份
  • 端口不同
    • http协议:使用的端口是80
    • https协议:使用的端口是443
  • 证书申请方式不同
    • http协议:无需申请证书
    • https协议:需要到ca申请证书,一般免费证书很少,需要交费

6. HTTP/HTPS安全性

6.1 HTTP的安全性问题
  • 使用明文进行通信,内容可能会被窃听
  • 不验证通信方的身份,通信方的身份有可能遭遇伪装
  • 无法证明报文的完整性,报文有可能遭篡改

HTTPs(Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲HTTPs是HTTP的安全版。HTTPs 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信。也就是说 HTTPs 使用了隧道进行通信。通过使用 SSL,HTTPs 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)

6.2 对称密钥加密

对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥

  • 优点:运算速度快;
  • 缺点:无法安全地将密钥传输给通信方
6.3 非对称密钥加密

非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密

非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确

  • 优点:可以更安全地将公开密钥传输给通信发送方
  • 缺点:运算速度慢
6.4 HTTPs 采用的加密方式

HTTPs 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证安全性,之后使用对称密钥加密进行通信来保证效率

7. SSL/TLS协议的握手过程

我们知道,HTTP 协议都是明文传输内容,在早期只展示静态内容时没有问题。伴随着互联网的快速发展,人们对于网络传输安全性的要求也越来越高,HTTPS 协议因此出现。如上图所示,在 HTTPS 加密中真正起作用的其实是 SSL/TLS 协议。SSL/TLS 协议作用在 HTTP 协议之下,对于上层应用来说,原来的发送接收数据流程不变,这就很好地兼容了老的 HTTP 协议,这也是软件开发中分层实现的体现

7.1 SSL (Secure Socket Layer,安全套接字层)

SSL为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取,当前为3.0版本

SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等

7.2 TLS (Transport Layer Security,传输层安全协议)

用于两个应用程序之间提供保密性和数据完整性

TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1,它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面

7.3 握手过程
  • 1-client hello: 握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Ciphers)和 SSL Version 等信息

  • 2-server hello: 第二步是服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的 Support Ciphers 里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到

  • 3-server certificate: 这一步是服务端将自己的证书下发给客户端,让客户端验证自己的身份,客户端验证通过后取出证书中的公钥

  • 4-Server Hello Done: Server Hello Done 通知客户端 Server Hello 过程结束

  • 5-Client Key Exchange: 上面客户端根据服务器传来的公钥生成了 PreMaster Key,Client Key Exchange 就是将这个 key 传给服务端,服务端再用自己的私钥解出这个 PreMaster Key 得到客户端生成的 Random3。至此,客户端和服务端都拥有 Random1 + Random2 + Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密。为什么要使用三个随机数呢?这是因为 SSL/TLS 握手过程的数据都是明文传输的,并且多个随机数种子来生成秘钥不容易被暴力破解出来

  • 6-Change Cipher Spec(Client): 这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了,是一条事件消息

  • 7-Finished(Client): 客户端发送Finished报文。该报文包含连接至今全部报文的整理校验值。这次握手协议是否能成功,要以服务器是否能够正确解密该报文作为判定标准

  • 8-Change Cipher Spec(Server): 服务器同样发送Change Cipher Spec报文给客户端

  • 9-Finished(Server): 服务器同样发送Finished报文给客户端

  • 10-11Application Data: 到这里,双方已安全地协商出了同一份秘钥,所有的应用层数据都会用这个秘钥加密后再通过 TCP 进行可靠传输

  • 12-Alert:warning, close notify: 最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,在这步之后再发送一种叫做MAC(Message Authentication Code)的报文摘要。MAC能够查知报文是否遭到篡改,从而保护报文的完整性

8. Get和Post区别

  • 一般约束为:GET是从服务器上获取数据,POST是向服务器传送数据

  • Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的

  • Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制

  • Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集

  • Get执行效率却比Post方法好。Get是form提交的默认方法

  • GET产生一个TCP数据包;POST产生两个TCP数据包(非必然,客户端可灵活决定)

9. 从输入网址到获得页面的网络请求过程

  1. 输入地址
  2. 浏览器查找域名的 IP 地址
  3. 浏览器向 web 服务器发送一个 HTTP 请求
  4. 服务器的永久重定向响应
  5. 服务器处理请求
  6. 服务器返回一个 HTTP 响应
  7. 浏览器显示 HTML
  8. 浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)

详细解读: 点击跳转至网页

10. TCP报头格式和UDP报头格式

网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。运输层提供了进程间的逻辑通信,运输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个运输层实体之间有一条端到端的逻辑通信信道

  • TCP和UDP的特点

    • 传输控制协议 TCP(Transmission Control Protocol)是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的(一对一)
    • 用户数据报协议 UDP(User Datagram Protocol)是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信。例如:视频传输、实时通信
  • TCP首部格式

    74.jpg
    • 序号 seq :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。[301,400]为序号301的数据长度,下一个则为401。
    • 确认号 ack :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
    • 数据偏移 :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度
    • 确认 ACK :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1
    • 同步 SYN :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。
    • 终止 FIN :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。
    • 窗口 :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的
  • UDP首部格式

    首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的

    73.jpg

11. TCP连接中如果断电怎么办

都已经断电了,还能怎么办,等电来

12. TCP滑动窗口

78.jpg

窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小

发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口

接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {32, 33} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收

13. TCP流量控制

  • 流量控制是为了控制发送方发送速率,保证接收方来得及接收
  • 接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据

14. TCP拥塞处理(Congestion Handling)

拥塞控制的一般原理:

  • 在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏——产生拥塞(congestion)。
  • 出现资源拥塞的条件:对资源需求的总和 > 可用资源
  • 若网络中有许多资源同时产生拥塞,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而下降

如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度

TCP 主要通过四种算法来进行拥塞控制:慢开始拥塞避免快重传快恢复

15. TCP的LISTEN状态是什么

TCP的LISTEN是服务器处于监听状态:

  • CLOSED: 初始状态
  • LISTEN: 服务器处于监听状态
  • TIME_WAIT: 客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL时间称为TIME_WAIT状态

16. Tcp中的拆包和粘包

  • 粘包: 在socket通讯过程中,如果通讯的一端一次性连续发送多条数据包,tcp协议会将多个数据包打包成一个tcp报文发送出去,这就是所谓的粘包
  • 拆包: 而如果通讯的一端发送的数据包超过一次tcp报文所能传输的最大值时,就会将一个数据包拆成多个最大tcp长度的tcp报文分开传输,这就叫做拆包

17. HTTP的请求和响应报文

  • 请求报文

    • 请求行:由三部分组成(请求方法、请求URL-不包括域名、HTTP版本协议)
    • 请求头:由关键字-值对组成,每行一对
    • 空行:通知服务器以下不再有请求头
    • 请求体
    84.jpg
  • 响应报文

    • 响应行:由三部分组成:服务器HTTP协议版本,响应状态码,状态码的文本描述
    • 响应头:由关键字-值对组成,每行一对
    • 空行:通知服务器以下不再有响应头
    • 响应体
    96.jpg

18. HTTP方法

  • GET:获取资源
    • 当前网络请求中,绝大部分使用的是GET方法
  • HEAD:获取报文首部
    • 和GET方法一样,但是不返回报文实体主体部分
    • 主要用于确认 URL 的有效性以及资源更新的日期时间等
  • POST:传输实体主体
    • POST 主要用来传输数据,而 GET 主要用来获取资源
  • PUT:上传文件
    • 由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法
  • PATCH:对资源进行部分修改
    • PUT 也可以用于修改资源,但是只能完全替代原始资源,PATCH 允许部分修改
  • DELETE:删除文件
    • 与 PUT 功能相反,并且同样不带验证机制
  • OPTIONS:查询支持的方法
    • 查询指定的 URL 能够支持的方法
    • 会返回 Allow:GET,POST,HEAD,OPTIONS 这样的内容
  • CONNECT:要求在与代理服务器通信时建立隧道
    • 使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输
  • TRACE:追踪路径
    • 服务器会将通信路径返回给客户端
    • 发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器就会减 1,当数值为 0 时就停止传输
    • 通常不会使用 TRACE,并且它容易受到 XST 攻击(Cross-Site Tracing,跨站追踪)

19. 如何理解HTTP协议是无状态的

  • HTTP协议是无状态的(stateless),指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系
  • HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)
  • 缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快

20. HTTP2.0特性

HTTP/2的通过支持请求与响应的多路复用来减少延迟,通过压缩HTTP首部字段将协议开销降至最低,同时增加对请求优先级和服务器端推送的支持

21. 什么是短连接和长连接

在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话

而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:

1
Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接

22. Client如何实现长连接

使用TCP协议的KeepAlive机制与HeartBeat心跳包

  • HeartBeat心跳包
  • TCP协议的KeepAlive机制

23. Quic有什么优点相比Http2

  • HTTP1: 有连接无法复用、队头阻塞、协议开销大和安全因素等多个缺陷
  • HTTP2: 通过多路复用、二进制流、Header 压缩等等技术,极大地提高了性能,但是还是存在着问题的
  • Quic: 基于 UDP 实现,是 HTTP3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议.quic中加密认证的报文(TCP 协议头部没有经过任何加密和认证,所以在传输过程中很容易被中间网络设备篡改,注入和窃听。比如修改序列号、滑动窗口。这些行为有可能是出于性能优化,也有可能是主动攻击)。这样只要对 QUIC 报文任何修改,接收端都能够及时发现,有效地降低了安全风险

此外quic还有向前纠错的能力,QUIC 协议有一个非常独特的特性,称为向前纠错 (Forward Error Correction,FEC),每个数据包除了它本身的内容之外,还包括了部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。向前纠错牺牲了每个数据包可以发送数据的上限,但是减少了因为丢包导致的数据重传,因为数据重传将会消耗更多的时间(包括确认数据包丢失、请求重传、等待新数据包等步骤的时间消耗)

24. Grpc的优缺点

gRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。gRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好

最底层为TCP或Unix Socket协议,在此之上是HTTP/2协议的实现,然后在HTTP/2协议之上又构建了针对Go语言的gRPC核心库。应用程序通过gRPC插件生产的Stub代码和gRPC核心库通信,也可以直接和gRPC核心库通信

优点:

  • protobuf二进制消息,性能好/效率高(空间和时间效率都很不错)
  • proto文件生成目标代码,简单易用
  • 序列化反序列化直接对应程序中的数据类,不需要解析后在进行映射(XML,JSON都是这种方式)
  • 支持向前兼容(新加字段采用默认值)和向后兼容(忽略新加字段),简化升级
  • 支持多种语言(可以把proto文件看做IDL文件)

缺点:

  • GRPC尚未提供连接池,需要自行实现
  • 尚未提供“服务发现”、“负载均衡”机制
  • 因为基于HTTP2,绝大部多数HTTP Server、Nginx都尚不支持,即Nginx不能将GRPC请求作为HTTP请求来负载均衡,而是作为普通的TCP请求(nginx1.9版本已支持)
  • Protobuf二进制可读性差(貌似提供了Text_Fromat功能)默认不具备动态特性(可以通过动态定义生成消息类型或者动态编译支持)

25. Http1和Http2和Grpc之间的区别是什么

在互联网流量传输只使用了几个网络协议。使用 IPv4 进行路由,使用 TCP 进行连接层面的流量控制,使用 SSL/TLS 协议实现传输安全,使用 DNS 进行域名解析,使用 HTTP 进行应用数据的传输

HTTP2和HTTP1相比的新特性包括:

  • 新的二进制格式(Binary Format)

    • HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮
  • 多路复用(MultiPlexing)

    • 连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面
  • Header压缩

    Header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小

  • 服务端推送(server push)

    • 服务端推送(server push),同SPDY一样,HTTP2.0也具有server push功能

Grpc的设计目标是在任何环境下运行,支持可插拔的负载均衡,跟踪,运行状况检查和身份验证。它不仅支持数据中心内部和跨数据中心的服务调用,它也适用于分布式计算的最后一公里,将设备,移动应用程序和浏览器连接到后端服务,同时,它也是高性能的,而 HTTP2 恰好支持这些

Grpc是基于http2的

  • HTTP2天然的通用性满足各种设备,场景
  • HTTP2的性能相对来说也是很好的,除非你需要极致的性能
  • HTTP2的安全性非常好,天然支持 SSL
  • HTTP2的鉴权也非常成熟
  • Grpc基于 HTTP2 多语言实现也更容易

26. 数字签名、数字证书、SSL、https是什么关系

HTTPS 是建立在密码学基础之上的一种安全通信协议,严格来说是基于 HTTP 协议和 SSL/TLS 的组合

HTTP协议是无状态的,主要是为了让HTTP协议尽可能简单,使得它能够处理大量事务。HTTP/1.1引入Cookie来保存状态信息

Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。它用于告知服务端两个请求是否来自同一浏览器,并保持用户的登录状态

  • 用途

    • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
    • 个性化设置(如用户自定义设置、主题等)
    • 浏览器行为跟踪(如跟踪分析用户行为等)
  • 创建过程

    • 服务器发送的响应报文包含Set-Cookie 首部字段,客户端得到响应报文后把 Cookie 内容保存到浏览器中
    • 客户端之后对同一个服务器发送请求时,会从浏览器中读出 Cookie 信息通过 Cookie 请求首部字段发送给服务器
  • 分类

    • 会话期 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效
    • 持久性 Cookie:指定一个特定的过期时间(Expires)或有效期(max-age)之后就成为了持久性的 Cookie
  • JavaScript 获取 Cookie

    • 通过 Document.cookie 属性可创建新的 Cookie,也可通过该属性访问非 HttpOnly 标记的 Cookie
  • Secure 和 HttpOnly

    • 标记为 Secure 的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性,Secure 标记也无法提供确实的安全保障
    • 标记为 HttpOnly 的 Cookie 不能被 JavaScript 脚本调用。因为跨域脚本 (XSS) 攻击常常使用 JavaScript 的 Document.cookieAPI 窃取用户的 Cookie 信息,因此使用 HttpOnly 标记可以在一定程度上避免 XSS 攻击
  • 作用域

    • Domain 标识指定了哪些主机可以接受 Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了 Domain,则一般包含子域名。例如,如果设置 Domain=mozilla.org,则 Cookie 也包含在子域名中(如 developer.mozilla.org)
    • Path 标识指定了主机下的哪些路径可以接受 Cookie(该 URL 路径必须存在于请求 URL 中)。以字符 %x2F (“/“) 作为路径分隔符,子路径也会被匹配

28. Session

除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全

Session 可以存储在服务器上的文件、数据库或者内存中,现在最常见的是将 Session 存储在内存型数据库中,比如 Redis

使用 Session 维护用户登录的过程如下:

  • 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
  • 服务器验证该用户名和密码
  • 如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 ID 称为 Session ID
  • 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中
  • 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之后的业务操作

应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下,例如转账等操作,除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式

86.jpg

29. Cookie与Session异同

Cookie 和 Session 都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力

  • 作用范围不同:Cookie 保存在客户端(浏览器),Session 保存在服务器端
  • 存取方式的不同:Cookie只能保存 ASCII,Session可以存任意数据类型,比如UserId等
  • 有效期不同:Cookie可设置为长时间保持,比如默认登录功能功能,Session一般有效时间较短,客户端关闭或者Session超时都会失效
  • 隐私策略不同:Cookie存储在客户端,信息容易被窃取;Session存储在服务端,相对安全一些
  • 存储大小不同: 单个Cookie 保存的数据不能超过 4K,Session可存储数据远高于Cookie

30. 浏览器禁用Cookie

此时无法使用 Cookie 来保存用户信息,只能使用 Session。除此之外,不能再将 Session ID 存放到 Cookie 中,而是使用 URL 重写技术,将 Session ID 作为 URL 的参数进行传递

31. Cookie与Session选择

  • Cookie 只能存储 ASCII 码字符串,而 Session 则可以存取任何类型的数据,因此在考虑数据复杂性时首选 Session
  • Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密
  • 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中

32. Unicode和ASCII以及Utf8的区别

  • Unicode 是字符集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储
  • ASCII 码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)
  • UTF-8 是编码规则

33. TFO的原理是什么

TCP快速打开(TCP Fast Open,TFO)是对TCP的一种简化握手手续的拓展,用于提高两端点间连接的打开速度

简而言之,就是在TCP的三次握手过程中传输实际有用的数据。这个扩展最初在Linux系统实现,Linux服务器,Linux系统上的Chrome浏览器,或运行在Linux上的其他支持的软件

它通过握手开始时的SYN包中的TFO cookie来验证一个之前连接过的客户端。如果验证成功,它可以在三次握手最终的ACK包收到之前就开始发送数据,这样便跳过了一个绕路的行为,更在传输开始时就降低了延迟

这个加密的Cookie被存储在客户端,在一开始的连接时被设定好。然后每当客户端连接时,这个Cookie被重复返回

请求Tcp Fast Open Cookie:

  • 客户端发送SYN数据包,该数据包包含Fast Open选项,且该选项的Cookie为空,这表明客户端请求Fast Open Cookie
  • 支持TCP Fast Open的服务器生成Cookie,并将其置于SYN-ACK数据包中的Fast Open选项以发回客户端
  • 客户端收到SYN-ACK后,缓存Fast Open选项中的Cookie

34. TIME_WAIT的作用

主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟

  • 可靠地实现TCP全双工连接的终止
  • 允许老的重复分节在网络中消逝

35. 网络的性能指标有哪些

通常是以4个指标来衡量网络的性能,分别是带宽、延时、吞吐率、PPS(Packet Per Second),它们表示的意义如下:

  • 带宽:表示链路的最大传输速率,单位是 b/s (比特 / 秒),带宽越大,其传输能力就越强
  • 延时:表示请求数据包发送后,收到对端响应,所需要的时间延迟。不同的场景有着不同的含义,比如可以表示建立 TCP 连接所需的时间延迟,或一个数据包往返所需的时间延迟
  • 吞吐率:表示单位时间内成功传输的数据量,单位是 b/s(比特 / 秒)或者 B/s(字节 / 秒),吞吐受带宽限制,带宽越大,吞吐率的上限才可能越高
  • PPS:全称是 Packet Per Second(包 / 秒),表示以网络包为单位的传输速率,一般用来评估系统对于网络的转发能

除了以上这四种基本的指标,还有一些其他常用的性能指标,比如:

  • 网络的可用性:表示网络能否正常通信
  • 并发连接数:表示 TCP 连接数量
  • 丢包率:表示所丢失数据包数量占所发送数据组的比率
  • 重传率:表示重传网络包的比例

36. 如何区分流量控制和拥塞控制

  • 拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷
  • 拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素
  • 流量控制往往指在给定的发送端和接收端之间的点对点通信量的控制
  • 流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收
  • 流量控制属于通信双方协商;拥塞控制涉及通信链路全局
  • 流量控制需要通信双方各维护一个发送窗、一个接收窗,对任意一方,接收窗大小由自身决定,发送窗大小由接收方响应的TCP报文段中窗口值确定;拥塞控制的拥塞窗口大小变化由试探性发送一定数据量数据探查网络状况后而自适应调整
  • 实际最终发送窗口 = min{流控发送窗口,拥塞窗口}

37. 解释RTO,RTT和超时重传

  • 超时重传:发送端发送报文后若长时间未收到确认的报文则需要重发该报文。可能有以下几种情况:
    • 发送的数据没能到达接收端,所以对方没有响应。
    • 接收端接收到数据,但是ACK报文在返回过程中丢失
    • 接收端拒绝或丢弃数据
  • RTO:从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间。就是重传间隔
    • 通常每次重传RTO是前一次重传间隔的两倍,计量单位通常是RTT。例:1RTT,2RTT,4RTT,8RTT……
    • 重传次数到达上限之后停止重传
  • RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定

38. 停止等待和超时重传

  • 停止等待:通常我们说如果A和B双方建立好tcp连接后就可以相互发送数据了,A为发送方,B为接收方。因为这里讨论可靠传输原理,所以把传输的数据单元称为分组。“停止等待”就是每发送完一个分组就停止发送,等待对方确认后再发送下一个分组。停止等待协议考虑了数据在网络中传输出现的几种情况来提供有效措施保障数据的可靠传输,下面我们就一一来介绍这几种情况
  • 超时重传:原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。影响超时重传机制协议效率的一个关键参数是重传超时时间(RTO,Retransmission TimeOut)

39. 交换机和路由器的区别

  • 交换机是一根网线上网,但是大家上网是分别拨号,各自使用自己的宽带,大家上网没有影响。而路由器比交换机多了一个虚拟拨号功能,通过同一台路由器上网的电脑是共用一个宽带账号,大家上网要相互影响
  • 交换机工作在中继层,交换机根据MAC地址寻址。路由器工作在网络层,根据IP地址寻址,路由器可以处理TCP/IP协议,而交换机不可以
  • 交换机可以使连接它的多台电脑组成局域网,如果还有代理服务器的话还可以实现同时上网功能而且局域网所有电脑是共享它的带宽速率的,但是交换机没有路由器的自动识别数据包发送和到达地址的功能。路由器可以自动识别数据包发送和到达的地址,路由器相当于马路上的警察,负责交通疏导和指路的
  • 举几个例子,路由器是小邮局,就一个地址(IP),负责一个地方的收发(个人电脑,某个服务器,所以你家上网要这个东西),交换机是省里的大邮政中心,负责由一个地址给各个小地方的联系。简单的说路由器专管入网,交换机只管配送,路由路由就是给你找路让你上网的,交换机只负责开门,交换机上面要没有路由你是上不了网的
  • 路由器提供了防火墙的服务。路由器仅仅转发特定地址的数据包,不传送不支持路由协议的数据包传送和未知目标网络数据包的传送,从而可以防止广播风暴

40. 子网掩码的作用

内网中192.168.1.199的前三组是网络号,后一组是主机号,子网掩码就是255.255.255.0

首先要说明的是:不是某个IP的网络号和主机号决定子网掩码是什么,而是子网掩码决定了某个IP地址的网络号与主机号是什么,IP地址是要搭配子网掩码使用的。例如上面的子网掩码决定了192.168.1.199的前三段192.168.1是网络号,最后一段199是主机号

我们再来理解子网掩码的作用,先举个例子,市面上的两个厂家都生产电子秤,每个厂家都坚称他们的秤最准,那你是怎么知道他们的秤到底准不准?很简单,你去找一个 1KG 的国际千克原器,各放到他们的秤上测量,如果秤的测量值是1KG,那这把秤就是准的,子网掩码的作用就相当于这个大家公认的国际千克原器,是我们测量两个IP是否属于同一个网段的一个工具(应该说是让你知道某个IP地址的网络号与主机号分别是什么)

41. WebSocket是什么

WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据

在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输

WebSocket本质上一种计算机网络应用层的协议,用来弥补http协议在持久通信能力上的不足

WebSocket 协议在2008年诞生,2011年成为国际标准。现在最新版本浏览器都已经支持了

它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种

WebSocket 的其他特点包括:

  • 建立在 TCP 协议之上,服务器端的实现比较容易
  • 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器
  • 数据格式比较轻量,性能开销小,通信高效
  • 可以发送文本,也可以发送二进制数据
  • 没有同源限制,客户端可以与任意服务器通信
  • 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
image.png
41.1 为什么需要WebSocket

我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

因为 HTTP 协议有一个缺陷:通信只能由客户端发起,不具备服务器推送能力

举例来说,我们想了解查询今天的实时数据,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用”轮询”:每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)

在 WebSocket 协议出现以前,创建一个和服务端进双通道通信的 web 应用,需要依赖HTTP协议,进行不停的轮询,这会导致一些问题:

  • 服务端被迫维持来自每个客户端的大量不同的连接
  • 大量的轮询请求会造成高开销,比如会带上多余的header,造成了无用的数据传输

http协议本身是没有持久通信能力的,但是我们在实际的应用中,是很需要这种能力的,所以,为了解决这些问题,WebSocket协议由此而生。并且在HTML5标准中增加了有关WebSocket协议的相关api,所以只要实现了HTML5标准的客户端,就可以与支持WebSocket协议的服务器进行全双工的持久通信了

41.2 WebSocket与HTTP的区别
  • 相同点: 都是一样基于TCP的,都是可靠性传输协议。都是应用层协议
  • 联系: WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的
  • WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息,而HTTP是单向的
  • WebSocket是需要浏览器和服务器握手进行建立连接的,而http是浏览器发起向服务器的连接
  • 注意: 虽然HTTP/2也具备服务器推送功能,但HTTP/2 只能推送静态资源,无法推送指定的信息
image.png
41.3 WebSocket和Socket的区别

Socket是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口。而WebSocket协议是一个完整的应用层协议,拥有一套完整的API

42. WebSocket协议的原理

与http协议一样,WebSocket协议也需要通过已建立的TCP连接来传输数据。具体实现上是通过http协议建立通道,然后在此基础上用真正的WebSocket协议进行通信,所以WebSocket协议和http协议是有一定的交叉关系的

首先,WebSocket 是一个持久化的协议,相对于 HTTP 这种非持久的协议来说。简单的举个例子吧,用目前应用比较广泛的 PHP 生命周期来解释

HTTP 的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次 HTTP 请求就结束了

在 HTTP1.1 中进行了改进,使得有一个 keep-alive,也就是说,在一个 HTTP 连接中,可以发送多个 Request,接收多个 Response。但是请记住 Request = Response, 在 HTTP 中永远是这样,也就是说一个 Request 只能有一个 Response。而且这个 Response 也是被动的,不能主动发起

首先 WebSocket 是基于 HTTP 协议的,或者说借用了 HTTP 协议来完成一部分握手

首先我们来看个典型的 WebSocket 握手

1
2
3
4
5
6
7
8
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

熟悉 HTTP 的童鞋可能发现了,这段类似 HTTP 协议的握手请求中,多了这么几个东西。

1
2
Upgrade: websocket
Connection: Upgrade

这个就是 WebSocket 的核心了,告诉 Apache 、 Nginx 等服务器:注意啦,我发起的请求要用 WebSocket 协议,快点帮我找到对应的助理处理~而不是那个老土的 HTTP。

1
2
3
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

首先, Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠我,我要验证你是不是真的是 WebSocket 助理

然后, Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同 URL 下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~

最后, Sec-WebSocket-Version 是告诉服务器所使用的 WebSocket Draft (协议版本),在最初的时候,WebSocket 协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么 Firefox 和 Chrome 用的不是一个版本之类的,当初 WebSocket 协议太多可是一个大难题。。不过现在还好,已经定下来啦~大家都使用同一个版本: 服务员,我要的是13岁的噢→_→

然后服务器会返回下列东西,表示已经接受到请求, 成功建立 WebSocket 啦

1
2
3
4
5
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

这里开始就是 HTTP 最后负责的区域了,告诉客户,我已经成功切换协议啦~

1
2
Upgrade: websocket
Connection: Upgrade

依然是固定的,告诉客户端即将升级的是 WebSocket 协议,而不是 mozillasocket,lurnarsocket 或者 shitsocket

然后, Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key 。 服务器:好啦好啦,知道啦,给你看我的 ID CARD 来证明行了吧

后面的, Sec-WebSocket-Protocol 则是表示最终使用的协议

至此,HTTP 已经完成它所有工作了,接下来就是完全按照 WebSocket 协议进行了

WebSocket连接的过程:

  • 首先,客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等
  • 然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据
  • 最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信

43. Websocket的优缺点

  • 优点: WebSocket协议一旦建议后,互相沟通所消耗的请求头是很小的;服务器可以向客户端推送消息了
  • 缺点: 少部分浏览器不支持,浏览器支持的程度与方式有区别(IE10)

44. WebSocket应用场景

  • 即时聊天通信
  • 多玩家游戏
  • 在线协同编辑/编辑
  • 实时数据流的拉取与推送
  • 体育/游戏实况
  • 实时地图位置
  • 即时Web应用程序:即时Web应用程序使用一个Web套接字在客户端显示数据,这些数据由后端服务器连续发送。在WebSocket中,数据被连续推送/传输到已经打开的同一连接中,这就是为什么WebSocket更快并提高了应用程序性能的原因。 例如在交易网站或比特币交易中,这是最不稳定的事情,它用于显示价格波动,数据被后端服务器使用Web套接字通道连续推送到客户端
  • 游戏应用程序:在游戏应用程序中,你可能会注意到,服务器会持续接收数据,而不会刷新用户界面。屏幕上的用户界面会自动刷新,而且不需要建立新的连接,因此在WebSocket游戏应用程序中非常有帮助
  • 聊天应用程序:聊天应用程序仅使用WebSocket建立一次连接,便能在订阅户之间交换,发布和广播消息。它重复使用相同的WebSocket连接,用于发送和接收消息以及一对一的消息传输
44.1 不能使用WebSocket的场景

如果我们需要通过网络传输的任何实时更新或连续数据流,则可以使用WebSocket。如果我们要获取旧数据,或者只想获取一次数据供应用程序使用,则应该使用HTTP协议,不需要很频繁或仅获取一次的数据可以通过简单的HTTP请求查询,因此在这种情况下最好不要使用WebSocket

注意: 如果仅加载一次数据,则RESTful Web服务足以从服务器获取数据

45. WebSocket断线重连

心跳就是客户端定时的给服务端发送消息,证明客户端是在线的, 如果超过一定的时间没有发送则就是离线了

45.1 如何判断在线或离线

当客户端第一次发送请求至服务端时会携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果不存在就存入db或者缓存中

第二次客户端定时再次发送请求依旧携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果存在就把上次的时间戳拿取出来,使用当前时间戳减去上次的时间

得出的毫秒秒数判断是否大于指定的时间,若小于的话就是在线,否则就是离线

45.2 如何解决断线问题

通过查阅资料了解到 nginx 代理的 websocket 转发,无消息连接会出现超时断开问题。网上资料提到解决方案两种,一种是修改nginx配置信息,第二种是websocket发送心跳包

  • 断线的可能原因1:websocket超时没有消息自动断开连接
    • 解决方案:这时候我们就需要知道服务端设置的超时时长是多少,在小于超时时间内发送心跳包,有2中方案:一种是客户端主动发送上行心跳包,另一种方案是服务端主动发送下行心跳包
  • 断线的可能原因2:websocket异常包括服务端出现中断,交互切屏等等客户端异常中断等
    • 当若服务端宕机了,客户端怎么做、服务端再次上线时怎么做?
    • 客户端则需要断开连接,通过onclose 关闭连接,服务端再次上线时则需要清除之间存的数据,若不清除 则会造成只要请求到服务端的都会被视为离线
    • 针对这种异常的中断解决方案就是处理重连,下面我们给出的重连方案是使用js库处理:引入reconnecting-websocket.min.js,ws建立链接方法使用js库api方法

46. WebSocket总结

  • WebSocket 是为了在 web 应用上进行双通道通信而产生的协议,相比于轮询HTTP请求的方式,WebSocket 有节省服务器资源,效率高等优点
  • WebSocket 中的掩码是为了防止早期版本中存在中间缓存污染攻击等问题而设置的,客户端向服务端发送数据需要掩码,服务端向客户端发送数据不需要掩码
  • WebSocket 中 Sec-WebSocket-Key 的生成算法是拼接服务端和客户端生成的字符串,进行SHA1哈希算法,再用base64编码
  • WebSocket 协议握手是依靠 HTTP 协议的,依靠于 HTTP 响应101进行协议升级转换

WebSocket相关知识参考链接:点击跳转


47. 内网穿透

47.1 什么是内网穿透

内网穿透,也就是 NAT 穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机

用一句话将就是:通过公网IP的端口映射实现能访问内网服务器的资源

47.2 实现方式

通过FRP开源方式实现

FRP使用 Go 语言开发,可以支持 Windows、Linux、macOS、ARM 等多平台部署。frp内网穿透无需多复杂的配置就可以达到比较好的穿透效果,具有较强的扩展性,支持tcp, udp, http, https 协议,并且 web 服务支持根据域名进行路由转发。此外,FRP 提供了一种新的代理类型 XTCP ,可以在传输大量数据时让流量不经过服务器中转,用于实现点对点穿透,当然,此功能并不能保证在你的网络环境 100% 可用,成功率较低,而且还要求访问端也得运行 FRP 客户端 (目前手机端ios没有frp客户端软件)。由于实现条件较多,所以有文件传输需求的朋友但必须用frp的朋友还是建议买带宽稍大一点的 VPS 会比较省心。frp适合有linux基础的个人,且需要自购一个云主机做中转,企业追求稳定可以考虑其他方式

FRP实现内网穿透,就在于使用反向代理,使得真实的服务端得以隐藏。当外部用户(client)请求访问服务端VPS的时候,服务端VPS是客户端的反向代理服务器,反向代理服务器会帮我们把请求转发到真实的服务器那里去。这样就实现了内网穿透。即:

  • Client = 外部用户
  • proxy = 公网服务器(需要在服务器上搭建FRP服务端)
  • Server = 内网服务器(需要在服务器上搭建FRP客户端)
image.png

本文链接:
https://huajun-chen.github.io/2022/10/28/计算机网络面试题/