计算机网络常见问题

基础知识

常见协议分层

  • 应用层:HTTP,负责封装请求内容
  • 传输层:TCP、UDP,负责把数据包送达具体应用
  • 网络层:IP,负责把数据包送达目标主机

TCP

TCP 三次握手、TCP 四次挥手

三次握手可以两次吗

为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。在 S ACK 的时候,C 可能已经关闭无法接受信息,导致网络资源浪费。

四次挥手可以三次吗

当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭,所以只能先回复一个 ACK 报文。只有等到服务端所有的报文都发送完了,才能发送 FIN 报文,因此不能一起发送。所以需要四次挥手。

客户端第一个「SYN」包丢了,怎么办?

客户端会尝试三次重传 SYN 包,间隔时间分别是 5.8s、24s、48s。建立一个新连接的最长时间限制为 75 秒。

服务端收到「SYN」并回复的「SYN, ACK」包丢了,怎么办?

客户端没收到 ACK 会以为是前面 SYN 丢了,尝试重传 SYN 包。
服务器端在超时时间内没有收到客户端发来的「ACK」包,也会触发重传,此时服务端处于 SYN_RCVD 状态,会依次等待 3s、6s、12s 后,重新发送「SYN, ACK」包。不同的操作系统下,重传的次数有不同的配置,比如 linux 默认是 5 。如果重试后还是没有收到,则会断开连接。
同时由于客户端在没有收到「SYN,ACK」时,也会进行重传,当客户端重传的「SYN」收到后,会立即重新发送「SYN,ACK」包。

客户端最后一次回复的「ACK」包丢了,怎么办?

客户端此时进入 ESTABLISHED 状态。
服务端因为收不到「ACK」会走重传机制,依然处于 SYN-RCVD 状态。如果此时接收到客户端真实发送来的数据包时,通过包内 ACK 的确认序号,会认为连接已建立,并进入 ESTABLISHED 状态。

客户端故意不发最后一次「SYN」包,怎么办?

这就是 SYN FLOOD 攻击,虽然服务器有重试的次数限制,但是随着数量累积,还是会有较大压力。

HTTP

HTTP 报文组成部分

请求报文:请求行、请求头、空行、请求体
响应报文:状态行、响应头、空行、响应体

HTTP/1.0 和 HTTP/1.1 特性

HTTP/1.0:

  • 默认没有复用 TCP 连接,connection: close,请求头中显式声明 keep-alive 可以开启
  • 前一个请求响应到达之后下一个请求才能发送,容易导致队头阻塞

HTTP/1.1:

  • 默认是 connection: keep-alive 保持持续连接,一般默认的连接时间长度是 5-15 秒,保持不必要的连接会影响性能
  • 管道化,可以不等第一个请求响应继续发送后面的请求,但响应的顺序还是按照请求的顺序返回
  • 缓存处理,新增 cache-control 和 etag

HTTP/2 特性

  • 减少传输数据量:通过二进制传输 和 Header 压缩实现
  • 多路复用:使用同一个 TCP 连接来传输一个域名下的所有请求,请求还可以有优先级。一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极大的提高传输性能。
  • 服务端推送:能够在客户端发送第一个请求到服务端时,提前把一部分内容推送给客户端,放入缓存当中,这可以避免客户端请求顺序带来的并行度不高,从而导致的性能问题。
  • 丢包重传会导致所有请求阻塞,这种情况下性能反而不如 HTTP/1。基于 QUIC 的 HTTP/3 可以彻底解决 TCP 的队头阻塞问题

HTTPS 的工作原理

  • 客户端连接 443 端口发送请求,包括:支持的加密压缩算法协议版本、一个随机数 r1
  • 服务器端返回结果,包括:确认加密算法、包含公钥的证书、一个随机数 r2
  • 客户端解析证书,验证证书的颁发机构和过期时间,如果证书没问题,则生成一个随机值 pre-master secret,用公钥对该随机值加密,发送给服务端
  • 服务端用私钥解密,得到 pre-master secret。至此,非对称加密过程结束,实现了身份认证和密钥协商。
  • 通过 r1、r2、pre-master secret 三个随机数生成一个 master secret,从而得到对话密钥集合 sessions keys ,以后的通讯都用这些密钥进行加密解密
  • 服务器端用随机值加密后传输信息给客户端
  • 客户端可以用之前生成的随机值还原出原文。至此,一个对称加密的过程结束,用于服务器端传送给客户端数据。
  • 因为非对称加密的性能很差,所以传输的时候用对称加密

参考资料