计算机网络常见问题

Created at 2020-01-29 Updated at 2020-07-29 Category 基础 Tag 计算机网络

七层协议

各层协议的作用

七层协议

物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

各层传输单位:

  • 物理层:比特流
  • 数据链路层:帧
  • 网络层:包
  • 传输层:报文

五层协议

  • 应用层:为特定应用程序提供数据传输服务。
  • 传输层:为进程提供通用数据传输服务。提供端对端的接口。
  • 网络层:为主机提供数据传输服务。为数据包选择路由。
  • 数据链路层:传输有地址的帧以及差错校验功能。
  • 物理层:以二进制在物理媒体上传输数据。

各层中的协议和设备:

  • 物理层:集线器、中继器
  • 数据链路层:网桥、交换机、PPP、ARP、RARP
  • 网络层:路由器、IP、ICMP、OSPF、RIP
  • 传输层:TCP、UDP
  • 应用层:HTTP、FTP、DNS、SMTP、Telnet

TCP/IP 协议

只有四层,相当于五层协议中数据链路层和物理层合并为网络接口层。TCP/IP 协议体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者网络接口层。

数据链路层和传输层的差错控制有什么区别

  • 数据链路层使用循环冗余检验码(CRC)校验
  • TCP使用校验和:TCP 的首部字段中有一个字段是校验和,发送方将伪首部、TCP首部、TCP数据使用累加和校验的方式计算出一个数字,然后存放在首部的校验和字段里,接收者收到TCP包后重复这个过程,然后将计算出的校验和和接收到的首部中的校验和比较,如果不一致则说明数据在传输过程中出错。

数据链路层的校验只覆盖物理链路,当以太网离开主机网卡前,添加了 CRC 校验,顺着物理链路流动到另一头,进入路由器接口之后。接收方(路由器)开始计算 CRC 校验,计算得到的 CRC 如果与接收的 CRC 相同,校验通过。将 CRC 剥离,接受并路由到另一个接口。

因为IP 报文在路由器内部可能需要做 “QPS”、“NAT” 等操作,这些操作都需要修改 IP、TCP 头的某些字段,所以还需要传输层校验。

以太网的特点,以及帧结构。

  • 以太网是一种星型拓扑结构局域网。
  • 以太网帧格式
  • 类型:标记上层使用的协议;
  • 数据:长度在 46-1500 之间秒如果太小则需要填充;
  • FCS:帧检验序列,使用的是 CRC 检验方法;

集线器、交换机、路由器的作用,以及所属的网络层

  • 集线器:物理层设备。作用于比特而不是帧,当一个比特到达接口时,集线器重新生成这个比特,并将其能量强度放大,从而扩大网络的传输距离,之后再将这个比特发送到其他所有接口。如果集线器同时收到两个不同接口的帧,那么就发生了碰撞。
  • 交换机:链路层设备。是一种基于 MAC 识别,能完成封装转发数据包功能的网络设备。它不会发生碰撞,能根据 MAC 地址进行存储转发。
  • 路由器:网络层设备。是一种连接多个网络或网段的网络设备,根据 IP 进行转发。

IP 数据数据报常见字段的作用。

  • 版本:有 4(IPv4)和 6(IPv6)两个值;
  • 首部长度 : 占 4 位,因此最大值为 15。值为 1 表示的是 1 个 32 位字的长度,也就是 4 字节。因为首部固定长度为 20 字节,因此该值最小为 5。如果可选字段的长度不是 4 字节的整数倍,就用尾部的填充部分来填充。
  • 区分服务 : 用来获得更好的服务,一般情况下不使用。
  • 总长度 : 包括首部长度和数据部分长度。
  • 生存时间 :TTL,它的存在是为了防止无法交付的数据报在互联网中不断兜圈子。以路由器跳数为单位,当 TTL 为 0 时就丢弃数据报。
  • 协议 :指出携带的数据应该上交给哪个协议进行处理,例如 ICMP、TCP、UDP 等。
  • 首部检验和 :因为数据报每经过一个路由器,都要重新计算检验和,因此检验和不包含数据部分可以减少计算的工作量。
  • 标识 : 在数据报长度过长从而发生分片的情况下,相同数据报的不同分片具有相同的标识符。
  • 片偏移 : 和标识符一起,用于发生分片的情况。片偏移的单位为 8 字节。

ARP 协议的作用,以及维护 ARP 缓存的过程。

  • ARP 实现由 IP 地址得到 MAC 地址
  • 如果主机 A 知道主机 B 的 IP 地址,但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射,此时主机 A 通过广播的方式发送 ARP 请求分组,主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址,随后主机 A 向其高速缓存中写入主机 B 的 IP 地址到MAC 地址的映射。

ICMP 报文种类以及作用;和 IP 数据报的关系;Ping 和 Traceroute 的具体原理。

  • ICMP 报文分为差错报告报文和询问报文
  • ICMP 是为了更有效地转发 IP 数据报和提高交付成功的机会。它封装在 IP 数据报中,但不属于高层协议
  • Ping 的原理是通过向目的主机发送 ICMP Echo 请求报文,目的主机收到之后会发送 Echo 回答报文。Ping 会根据时间和成功相应次数估算出数据包往返时间以及丢包率
  • Traceroute 发送的 IP 数据报封装的是无法交付的 UDP 用户数据报,并由目的主机发送终点不可达差错报告报文。
  • 源主机向目的主机发送一连串的 IP 数据报。第一个数据报 P1 的生存时间 TTL 设置为 1,当 P1 到达路径上的第一个路由器 R1 时,R1 收下它并把 TTL 减 1,此时 TTL 等于 0,R1 就把 P1 丢弃,并向源主机发送一个 ICMP 时间超过差错报告报文;
  • 源主机接着发送第二个数据报 P2,并把 TTL 设置为 2。P2 先到达 R1,R1 收下后把 TTL 减 1 再转发给 R2,R2 收下后也把 TTL 减 1,由于此时 TTL 等于 0,R2 就丢弃 P2,并向源主机发送一个 ICMP 时间超过差错报文。
  • 不断执行这样的步骤,直到最后一个数据报刚刚到达目的主机,主机不转发数据报,也不把 TTL 值减 1。但是因为数据报封装的是无法交付的 UDP,因此目的主机要向源主机发送 ICMP 终点不可达差错报告报文。
  • 之后源主机知道了到达目的主机所经过的路由器 IP 地址以及到达每个路由器的往返时间。

UDP 与 TCP 比较,分析上层协议应该使用 UDP 还是 TCP。

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

当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP 等邮件传输的协议。当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP(如视频传输、实时通信等)。

理解三次握手以及四次挥手具体过程,三次握手的原因、四次挥手原因、TIME_WAIT 的作用。

三次握手过程:

  1. 服务器处于 LISTEN 状态,等待来自客户端的连接请求
  2. 客户端向服务器发送连接请求报文 SYN 段,并指明客户端的初始序列号 ISN(c)
  3. 服务器收到客户端发来的 SYN,如果同意建立连接,则向客户端发送确认报文 SYN = ISN(s),并将 ISN(c)+1 作为ACK 数值,这样每发送一个 SYN,序列号加1,如果有丢失的情况,就会重传。
  4. 客户端收到 SYN ACK 后,还要向服务器发出确认报文 ACK,ACK 的值为 ISN(s)+1。
  5. 服务器收到 ACK 后,连接建立
  • 连接建立以后,ACK 都置为 1

  • 第三次握手可以携带数据,如果不携带数据则不消耗序号

  • 三次握手的原因:第三次握手是为了确认客户端的接收能力。

如果是两次,客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认,客户端超时重发连接请求,这样服务器会对同一个客户端保持多个连接,造成资源浪费。

握手只需要确认双方通信时的初始化序号(ISN 是随机的,防止攻击者猜出确认号和防止同一个连接的不同实例),保证通信不会乱序。

四次挥手:

  • 客户端(主动关闭方)发送释放报文 FIN
  • 服务器(被动关闭方)收到 FIN 后发出确认 ACK,此时 TCP 属于半关闭状态(CLOSED_WAIT),服务器能向客户端发送数据但是客户端不能向服务器发送数据
  • 当服务器不再需要连接时,发送连接释放报文 FIN
  • 客户端收到 FIN 后发出确认 ACK,进入 TIME-WAIT 状态,等待 2 倍的 MSL(最大报文存活时间)后释放连接
  • 服务器收到 ACK 后释放连接

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

TIME_WAIT:客户端收到服务端的 FIN 报文址后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:

  1. 确保最后一个报文能够到达。如果服务器没收到客户端发送来的确认报文(网络不好),那么就会重新发送连接释放请求报文(被动方重传或延迟的 FIN 包),收到后会给被动方回一个 RST 包,可能会影响被动方其他的服务连接。
  2. 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,确保下一个连接不会出现旧的连接请求报文。有可能新连接和老连接的端口号是相同的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达 Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。

TIME-WAIT 过多造成的问题

高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接。这个场景下会出现大量 socket 处于 TIME_WAIT 状态,系统会把多余的 TIME_WAIT socket 删除掉,并且显示警告信息。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。

MSL 时间:maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间IP数据包将在网络中消失 。MSL在RFC 793上建议是2分钟。

在流量大的网站或者服务器上,可以调整 Windows 预设的 TIME-WAIT,微软建议最低可设 30 秒。

vim /etc/sysctl.conf

编辑文件,加入以下内容

net.ipv4.tcp_syncookies = 1 //表示开启 SYN Cookies。当出现 SYN 等待队列溢出时,启用 Cookies 来处理,可防范少量 SYN 攻击,默认为 0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 //表示开启重用,允许将 TIME-WAIT sockets 重新用于新的 TCP 连接,默认为 0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 //表示开启 TCP 连接中的 TIME-WAIT sockets 的快速回收,默认为 0,表示关闭(尽量不要开启);
net.ipv4.tcp_fin_timeout = 30 //修改系统默认的 TIMEOUT 时间
tcp_max_tw_buckets = 256000 // 当出现 TCP: time wait bucket table overflow 时,调大这个参数

造成 TIME-WAIT 过多的原因还有可能是 http 连接未关闭。

由于 keepalive 存在,一般服务端都会有 keepalive 超时设置。如果到了超时时间,客户端没有断开连接,服务端会主动断开。这种情况下,服务端会采用四次挥手方式断开连接,但是由于客户端对象已经没有任何引用,不会调用 close 方法,客户端虽然接收到了服务端发过来的fin包,但是不会回fin包,所以连接无法正常断开:客户端将处于 close-wait 状态,等待 gc 回收,服务端将处于 fin-wait-2 状态,并等待超时,进入 time-wait 状态。

说说半连接队列和 SYN Flood 攻击的关系

三次握手前,服务端的状态从 CLOSED 变为 LISTEN,同时在内部创建了两个队列:半连接队列和全连接队列,即 SYN 队列和 ACCEPT 队列。

  • 半连接队列:当客户端发送 SYN 到服务端,服务端收到以后回复 ACK 和 SYN,状态由 LISTEN 变为SYN_RCVD,此时这个连接就被推入了 SYN 队列,也就是半连接队列。
  • 全连接队列:当客户端返回ACK, 服务端接收后,三次握手完成。这个时候连接等待被具体的应用取走,在被取走之前,它会被推入另外一个 TCP 维护的队列,也就是全连接队列(Accept Queue)。

SYN Flood 攻击原理:SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP 地址,并向服务端疯狂发送 SYN。对于服务端而言,会产生两个危险的后果:

  1. 处理大量的 SYN 包并返回对应 ACK, 势必有大量连接处于 SYN_RCVD 状态,从而占满整个半连接队列,无法处理正常的请求。
  2. 由于是不存在的 IP,服务端长时间收不到客户端的 ACK,会导致服务端不断重发数据,直到耗尽服务端的资源。

如何应对:

  1. 增加 SYN 连接,也就是增加半连接队列的容量。
  2. 减少 SYN + ACK 重试次数,避免大量的超时重发。
  3. 利用 SYN Cookie 技术,在服务端接收到 SYN 后不立即分配连接资源,而是根据这个 SYN 计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复 ACK 的时候带上这个 Cookie 值,服务端验证 Cookie 合法之后才分配连接资源。

可靠传输原理,并设计可靠 UDP 协议。

  • 建立连接(标志位):通信前确认通信实体存在
  • 序号机制(序号、确认号):确保了数据是按序、完整到达
  • 数据校验(校验和):CRC 校验全部数据,校验包出错,丢弃报文段,不给出响应,超时重发
  • 超时重传(定时器):保证因链路故障未能到达数据能够被多次重发。
    • RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。
    • RTO:重传间隔,通常每次重传 RTO 是前一次重传间隔的两倍,重传次数达到上限后停止重传。RTO = RTTs + 4*RTTd
  • 流量控制(流量窗口)
  • 拥塞控制(拥塞窗口)

流量控制的作用,原理。

目的是避免发送过量,接收方通过 TCP 头窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题。

  • 发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段来告诉发送方自己的窗口大小,发送方根据这个值来设置自己窗口大小。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态,接收窗口类似。
  • TCP 是流数据,发送出去的数据流可以被分为以下四部分:已发送且被确认部分 | 已发送未被确认部分 | 未发送但可发送部分 | 不可发送部分,其中发送窗 = 已发送未确认部分 + 未发但可发送部分。接收到的数据流可分为:已接收 | 未接收但准备接收 | 未接收不准备接收。接收窗 = 未接收但准备接收部分。
  • 发送窗内的数据只有当收到接收端某段发送数据的 ACK 响应时才移动发送窗。接收窗口只会对窗口最后一个按序到达的字节进行确认。

TCP 拥塞控制的作用,理解具体原理。

作用:为了降低整个网络的拥塞程度。

拥塞控制使用拥塞窗口。TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。

  • 慢开始:发送的最初执行慢开始,令拥塞窗口 cwnd(congestion window) = 1,发送方只能发送一个报文段,当收到确认后,将 cwnd 加倍。
  • 拥塞避免:设置一个慢开始门限 ssthresh ,当cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。
  • 快重传:在发送方,如果收到 3 个重复确认,那么知道下一个报文段丢失,此时执行快重传,立刻重传下一个报文段。
  • 快恢复:快重传之后执行快恢复,令 ssthresh = cwnd / 2,cwnd = ssthresh,此时直接进入拥塞避免。

慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。

  • 流量控制和拥塞控制:
    • 流量控制属于通信双方协商,拥塞控制涉及通信链路全局
    • 实际最终发送窗口 = min{awnd(流量控制发送窗口),cwnd(拥塞窗口)}

DNS 的端口号;TCP 还是 UDP;作为缓存、负载均衡。

DNS可以使用 UDP 和 TCP 进行传输,使用的端口号都为53。大多数情况下 DNS 使用 UDP 进行传输,这就要求域名解析器和域名服务器都必须自己处理超市和重传来保证可靠性。在两种情况下会使用 TCP 进行传输:

  1. 如果返回的响应超过 512 字节(UDP 最大只支持 512 字节的数据)。
  2. 区域传送(区域传送是主域名服务器向辅助域名服务器传送变化的那部分数据)。

IP 协议的作用

DNS 寻址过程

  • 浏览器 DNS 缓存
  • 系统 DNS 缓存
  • 本地 DNS 服务器
  • 根 DNS 服务器
  • 顶级 DNS 服务器
  • 域名 DNS 服务器

HTTP

GET 与 POST 比较:作用、参数、安全性、幂等性、可缓存。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/GET

GET POST
请求是否有主体
安全
幂等
可缓存
作用 获取资源 传输实体主体
参数 以查询字符串出现在 URL 中 存储在实体主体中

安全性:安全的 HTTP 方法不会改变服务器状态,也就是说他只是可读的。

幂等性:幂等的 HTTP 方法,同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。所有的安全方法也都是幂等的。在正确实现的条件下,GET,HEAD,PUT 和 DELETE 等方法都是幂等的,而 POST 方法不是。

HTTP 状态码。

状态码 类别 含义
1XX Informational(信息性状态码) 接受的请求正在处理
2XX Successful(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器请求处理出错
  • 100 Continue:表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。

  • 200 Ok

  • 204 No Content:请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。

  • 206 Partial Content:表示客户端进行了范围请求,响应报文包含由 Conent-Range 指定范围的实体内容。

  • 301 Moved Permanently:永久重定向

  • 302 Found:临时性重定向

  • 303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。

    注:虽然 HTTP 协议规定 301、302 状态下重定向时不允许把 POST 方法改成 GET 方法,但是大多数浏览器都会在 301、302 和 303 状态下的重定向把 POST 方法改成 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 方法。

  • 400 Bad Request:请求报文中存在语法错误

  • 401 Unauthorized:该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。

  • 403 Fobidden:请求被拒绝

  • 404 Not Found

  • 500 Internal Server Error :服务器正在执行请求时发生错误。

  • 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

  • Session 在服务端,Cookie 在客户端(浏览器)

  • Session 的运行依赖 session_id,session_id 存在 Cookie 中,如果浏览器禁用可以用其他方式实现,比如在 URL 中传递 session_id。

用途:

  1. 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  2. 个性化设置(如用户自定义设置、主题等)
  3. 浏览器行为跟踪(如跟踪分析用户行为等)
  • 标记为 HttpOnly 的 Cookie 不能被 Javascript 脚本调用。跨站脚本攻击 (XSS) 常常使用 JavaScript 的 document.cookie API 窃取用户的 Cookie 信息,因此使用 HttpOnly 标记可以在一定程度上避免 XSS 攻击。
  • 标记为 Secure 的 Cookie 只能通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性,Secure 标记也无法提供确实的安全保障。

Cookie 与 Session 选择

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

缓存的 Cache-Control 字段,特别是 Expires 和 max-age 的区别。ETag 验证原理。

HTTP/1.1 通过 Cache-Control 首部字段来控制缓存。

  • no-store 指令规定不能对请求或响应的任何一部分进行缓存 Cache-Control:no-store

  • no-cache 指令规定缓存服务器需要先向源服务器验证缓存的有效性,只有当缓存服务器有效才将能使用该缓存对客户端的请求进行相应

  • private 指令规定了将资源作为私有缓存,只能被单独用户所使用,一般存储在用户浏览器中。public 指令规定了将资源作为公共缓存,可以被多个用户所使用,一般存储在代理服务器中。

  • max-age 指令出现在请求报文中,并且缓存资源的缓存时间小于该指令指定的时间,那么就能接受该缓存。max-age 指令出现在响应报文中,表示缓存资源在缓存服务器中保存的时间。Expires 首部字段也可以用于告知缓存服务器该资源什么时候会过期。在 HTTP/1.1 中,会优先处理 max-age 指令;在 HTTP/1.0 中,max-age 指令会被忽略掉。

ETag:它是资源的唯一标识。URL 不能唯一表示资源,例如 http://www.google.com/ 有中文和英文两个资源,只有 ETag 才能对这两个资源进行唯一标识。ETag: "82e22293907ce725faf67773957acd12"可以将缓存资源的 ETag 值放入 If-None-Match 首部,服务器收到该请求后,判断缓存资源的 ETag 值和资源的最新 ETag 值是否一致,如果一致则表示缓存资源有效,返回 304 Not Modified。 If-None-Match: "82e22293907ce725faf67773957acd12"

304 也是一种很好的缓存手段:服务器响应文件内容时,同时响应 etag 标签(内容的签名,内容变了他就变), 和 last_modified_since 两个标签值。浏览器下次去请求时,头信息发送这两个标签,,服务器检测文件有没有发生变化,如无,直接头信息返回 etag,last_modified_since。浏览器知道内容无改变,于是直接调用本地缓存。这个过程,也请求了服务器,但是传输的内容极少。对于变化周期较短的,如静态 html、js、css 比较适于用这个方式。

长连接与短连接原理以及使用场景,流水线。

关于HTTP协议中的保持连接

  • 当浏览器访问一个包含多张图片的 HTML 页面时,除了请求访问 HTML 页面资源,还会请求图片资源。如果每进行一次 HTTP 通信就要新建一个 TCP 连接,那么开销会很大。长连接只需要建立一次 TCP 连接就能进行多次 HTTP 通信。

  • 从 HTTP/1.1 开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用 Connection : close

  • 在 HTTP/1.1 之前默认是短连接的,如果需要使用长连接,则使用 Connection : Keep-Alive

  • 短连接:连接->传输数据->关闭连接

  • 长连接:连接->传输数据->保持连接 -> 传输数据-> ………..->直到一方关闭连接,多是客户端关闭连接。

HTTP的长连接和短连接本质上是 TCP 长连接和短连接。

  • HTTP 1.0 默认使用短连接,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。
  • HTTP 1.1 默认使用长连接。使用长连接的HTTP协议,会在响应头有加入这行代码 Connection:keep-alive
  • TCP 短连接:短连接一般只会在 client/server 间传递一次读写操作。优点是管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。
  • TCP 长连接:Client 与 server 完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

心跳包用来解决半连接问题。
当服务器断电、断网、丢弃三次握手的ack包都可能造成客户端半连接,同时客户端断电、断网,或者中间设备故障也可能造成服务器端半连接。
半连接出现后,从系统层面考虑,对服务器而言,害怕的是量大导致资源耗尽从而拒绝服务;对客户端而言,系统危害不大,连接一致性无法保证。从业务层面而言,如果是长连接的推送服务,如果客户端故障导致,将导致推送数据失败。

TCP 的保活功能:主要为服务器应用提供。如果客户端已经消失而连接未断开,则会使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,此时服务器将永远等待客户端的数据。保活功能就是试图在服务端器端检测到这种半开放的连接。在 Linux 操作系统中,我们可以通过代码启用一个 socket 的心跳检测(即每隔一定时间间隔发送一个心跳检测包给对端)。

应用层心跳包:TCP 提供的 KeepAlive 机制无法代替心跳包。为了保持长连接,它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。

HTTP 存在的安全性问题,以及 HTTPs 的加密、认证和完整性保护作用。

安全性问题:

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

HTTPs:让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是说 HTTPs 使用了隧道进行通信。通过使用 SSL,HTTPs 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。

  1. 客户端请求服务器获取证书公钥
  2. 客户端(SSL/TLS)解析证书(无效会弹出警告)
  3. 生成随机值
  4. 公钥加密随机值生成密钥
  5. 客户端将秘钥发送给服务器
  6. 服务端用私钥解密秘钥得到随机值
  7. 将信息和随机值混合在一起进行对称加密
  8. 将加密的内容发送给客户端
  9. 客户端用秘钥解密信息

什么是队头阻塞

TCP 队头阻塞

TCP 要求数据严格按照序号顺序,如果第一个 TCP 分节丢失了,客户端将一直等待丢失的分节重传成功,这样就延缓了后面数据的接收。

如何解决:不使用 TCP 协议,比如 google 推出的 quic 协议,它是在 UDP 基础上实现的可靠传输。还有一个 SCTP(流控制传输协议),它是和 TCP,UDP 在同一层次的传输协议。SCTP 的多流特性也可以尽可能的避免队头阻塞的情况。

HTTP 1.1 队头阻塞

HTTP 1.1 允许在持久连接上可选的使用管道化(pipeline)特性。管道化允许客户端在已发送的请求收到服务端的响应之前发送下一个请求,,借此来减少等待时间提高吞吐;如果多个请求能在同一个TCP分节发送的话,还能提高网络利用率。

但是管道化要求服务端按照请求发送的顺序返回响应,因为 HTTP 请求和响应没有序号标识,无法将乱序的响应与请求关联起来。所以一个响应返回延迟了,后续的响应都会被延迟,直到队头的响应送达。

如何解决:使用 HTTP 2.0。HTTP 2.0 采用二进制分帧,将阐述信息分割为更小的消息和帧,对他们采用二进制格式编码。比如 header 帧,Data 帧。这些帧可以打散乱序发送,然后根据每个帧首部的流标识符重新组装,并且可以根据优先级,决定优先处理哪个流的数据。

HTTP/1.x 的缺陷,以及 HTTP/2 的特点。

  • HTTP/1.X 缺陷:
    • 客户端需要使用多个连接才能实现并发和缩短延迟
    • 不会压缩请求和响应首部,从而导致不必要的网络流量
    • 不支持有效的资源优先级,导致底层 TCP 连接的利用率低下
    • 客户端需要主动请求
    • 队头阻塞
  • HTTP/2:
    • 二进制分帧层:HTTP 2 是二进制协议,他下用二进制格式传输数据而不是 1.x 的文本格式。它将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式的。在通信过程中,只会有一个 TCP 连接存在,它承载力任意数量的数据流。
    • 服务器推送:HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 page.html 页面,服务端就把 script.js 和 style.css 等与之相关的资源一起发给客户端。
    • 首部压缩:HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见过的首部字段表,从而避免了重复传输。不仅如此,HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。
    • 多路复用:HTTP2 让所有的通信都在一个 TCP 连接上完成,实现了请求并发,后面的请求不用再等待,解决了队头阻塞。

HTTP/1.1 的特性。

  • 默认是长连接
  • 支持流水线
  • 支持同时打开多个 TCP 连接
  • 支持虚拟主机
  • 新增状态码 100
  • 支持分块传输编码
  • 新增缓存处理指令 max-age

HTTP 与 FTP 的比较。

  • FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件
  • 控制连接:服务器打开端口号 21 等待客户端的连接,客户端主动建立连接后,使用这个连接将客户端的命令传送给服务器,并传回服务器的应答
  • 数据连接:用来传送一个文件数据

参考文章

Table of Content

  1. 七层协议
    1. 各层协议的作用
      1. 七层协议
      2. 五层协议
      3. TCP/IP 协议
    2. 数据链路层和传输层的差错控制有什么区别
    3. 以太网的特点,以及帧结构。
    4. 集线器、交换机、路由器的作用,以及所属的网络层
    5. IP 数据数据报常见字段的作用。
    6. ARP 协议的作用,以及维护 ARP 缓存的过程。
    7. ICMP 报文种类以及作用;和 IP 数据报的关系;Ping 和 Traceroute 的具体原理。
    8. UDP 与 TCP 比较,分析上层协议应该使用 UDP 还是 TCP。
    9. 理解三次握手以及四次挥手具体过程,三次握手的原因、四次挥手原因、TIME_WAIT 的作用。
    10. TIME-WAIT 过多造成的问题
    11. 说说半连接队列和 SYN Flood 攻击的关系
    12. 可靠传输原理,并设计可靠 UDP 协议。
    13. 流量控制的作用,原理。
    14. TCP 拥塞控制的作用,理解具体原理。
    15. DNS 的端口号;TCP 还是 UDP;作为缓存、负载均衡。
    16. IP 协议的作用
    17. DNS 寻址过程
  2. HTTP
    1. GET 与 POST 比较:作用、参数、安全性、幂等性、可缓存。
    2. HTTP 状态码。
    3. Cookie 作用、安全性问题、和 Session 的比较。
    4. 缓存的 Cache-Control 字段,特别是 Expires 和 max-age 的区别。ETag 验证原理。
    5. 长连接与短连接原理以及使用场景,流水线。
    6. HTTP 存在的安全性问题,以及 HTTPs 的加密、认证和完整性保护作用。
    7. 什么是队头阻塞
      1. TCP 队头阻塞
      2. HTTP 1.1 队头阻塞
    8. HTTP/1.x 的缺陷,以及 HTTP/2 的特点。
    9. HTTP/1.1 的特性。
    10. HTTP 与 FTP 的比较。
  3. 参考文章
Site by Cellophane using Hexo & Random

Hide