CS-Notes全部笔记在阅读器中打开

计算机网络 - 应用层

本文目录

域名系统

DNS 是一个分布式数据库,提供了主机名和 IP 地址之间相互转换的服务。这里的分布式数据库是指,每个站点只保留它自己的那部分数据。

域名具有层次结构,从上到下依次为:根域名、顶级域名、二级域名。例如 com 是顶级域名,example.com 是二级域名,www.example.com 是三级域名;完整的写法是 www.example.com.,最右边的点代表根。

以解析 www.example.com 为例:主机先查浏览器缓存、操作系统缓存和 hosts 文件,没有命中就向本地 DNS 服务器查询。本地 DNS 服务器依次询问根服务器、com 顶级域服务器和 example.com 的权威服务器,前两者只返回下一级服务器的地址,权威服务器返回最终的 IP 地址。

域名系统的配图

主机到本地 DNS 服务器是递归查询,主机只等最终结果;本地 DNS 服务器到其它服务器是迭代查询,由它自己一步步问下去。每一级的结果都按 TTL 缓存,所以大多数查询在本地 DNS 服务器甚至主机上就能得到结果。

TTL 是每条记录自带的缓存时间,单位为秒,由权威服务器给出,缓存中的记录每过一秒剩余时间减 1。例如把公共 DNS 223.5.5.5 作为本地 DNS 服务器,查询 www.jd.com(dig 实测,见附录 A2):

www.jd.com.                           74  IN  CNAME  www.jd.com.gslb.qianxun.com.
www.jd.com.gslb.qianxun.com.          11  IN  CNAME  www.jd.com.s.galileo.jcloud-cdn.com.
www.jd.com.s.galileo.jcloud-cdn.com.  20  IN  CNAME  wwwv6.jcloudimg.com.
wwwv6.jcloudimg.com.                  15  IN  A      119.147.159.135

每行是一条资源记录:名字、剩余的 TTL、类别 IN(互联网)、类型和值。常见的类型有 A(IPv4 地址)、AAAA(IPv6 地址)、CNAME(别名,指向另一个域名)、NS(该区域的权威服务器)和 MX(邮件服务器)。

第二列是剩余的 TTL,5 秒后再查询,四个值都减少了 5;直接问京东的权威服务器,第一条记录的 TTL 是 120。修改记录后,各级缓存中的旧记录要等 TTL 到期才会失效,所以更换服务器的 IP 地址之前,通常先把 TTL 调小。

这个结果也说明了 CDN 的调度方式:www.jd.com 通过 CNAME(别名记录)把解析交给 CDN 的调度系统,调度系统根据查询来源的位置返回较近的节点地址,TTL 只有几十秒,便于随时切换节点。DNS 负载均衡见 DNS 域名解析,CDN 见 CDN。

DNS 可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。大多数情况下 DNS 使用 UDP 进行传输:一次查询只是一问一答,报文通常只有几十到几百字节,用 UDP 一个往返就能得到结果,TCP 还要先三次握手,服务器也要为每个连接保存状态。代价是域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。在两种情况下会使用 TCP 进行传输:

DNS 报文默认不加密,也不验证来源,常见的攻击有两种:DNS 劫持指的是攻击者控制了用户使用的 DNS 服务器或路由器,把域名解析到自己的地址;DNS 污染指的是在查询途中抢先返回伪造的响应,解析器会接受先到达的那个。如果递归解析器接受了伪造的记录并缓存下来,就造成了缓存投毒(DNS Cache Poisoning):记录过期或被清除之前,命中这条缓存的查询都会得到错误的地址。防范的方法:

文件传送协议

FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件:

根据数据连接是否是服务器端主动建立,FTP 有主动和被动两种模式:

文件传送协议的配图

主动模式要求客户端开放端口号给服务器端,需要去配置客户端的防火墙。被动模式只需要服务器端开放端口号即可,无需客户端配置防火墙。但是被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。

动态主机配置协议

动态主机配置协议(Dynamic Host Configuration Protocol, DHCP)提供了即插即用的连网方式,用户不再需要手动配置 IP 地址等信息。

DHCP 配置的内容不仅是 IP 地址,还包括子网掩码、网关 IP 地址和 DNS 服务器的地址。

分配的地址有租期,客户端在租期过半时向原服务器续租,到期没有续上就要停止使用这个地址。

DHCP 工作过程如下:

  1. 客户端发送 Discover 报文,该报文的目的地址为 255.255.255.255:67,源地址为 0.0.0.0:68,被放入 UDP 中,该报文被广播到同一个子网的所有主机上。如果客户端和 DHCP 服务器不在同一个子网,就需要使用中继代理。
  2. DHCP 服务器收到 Discover 报文之后,发送 Offer 报文给客户端,该报文包含了客户端所需要的信息。因为客户端可能收到多个 DHCP 服务器提供的信息,因此客户端需要进行选择。
  3. 如果客户端选择了某个 DHCP 服务器提供的信息,那么就广播 Request 报文,在其中用服务器标识选项指明选中的是哪个 DHCP 服务器,其它服务器收到后就知道自己的 Offer 没有被选中。
  4. DHCP 服务器发送 Ack 报文,表示客户端此时可以使用提供给它的信息。
动态主机配置协议的配图

远程登录协议

TELNET 用于登录到远程主机上,并且远程主机上的输出也会返回。

TELNET 可以适应许多计算机和操作系统的差异,例如不同操作系统的换行符定义。TELNET 以明文传输,包括密码,现在远程登录一般使用加密的 SSH。

电子邮件协议

一个电子邮件系统由三部分组成:用户代理、邮件服务器以及邮件协议。

邮件协议包含发送协议和读取协议,发送协议常用 SMTP,读取协议常用 POP3 和 IMAP。

电子邮件协议的配图

1. SMTP

SMTP 只能发送 ASCII 码,而互联网邮件扩充 MIME 可以发送二进制文件。MIME 并没有改动或者取代 SMTP,而是增加邮件主体的结构,定义了非 ASCII 码的编码规则。

1. SMTP 的配图

2. POP3

POP3 通常用“下载并删除”的方式使用:客户端下载邮件后发送 DELE 命令把服务器上的邮件删除;客户端也可以不发 DELE,选择在服务器上保留邮件。邮件的已读状态、文件夹等不会在多个设备之间同步。

3. IMAP

IMAP 协议中客户端和服务器上的邮件保持同步,如果不手动删除邮件,那么服务器上的邮件也不会被删除。IMAP 这种做法可以让用户随时随地去访问服务器上的邮件。

常用端口

应用 应用层协议 端口号 传输层协议 备注
域名解析 DNS 53 UDP/TCP 响应被截断或 AXFR 时使用 TCP
动态主机配置协议 DHCP 67/68 UDP
简单网络管理协议 SNMP 161/162 UDP
文件传送协议 FTP 20/21 TCP 控制连接 21,数据连接 20
安全外壳协议 SSH 22 TCP
远程终端协议 TELNET 23 TCP
超文本传送协议 HTTP 80 TCP
超文本传送安全协议 HTTPS 443 TCP HTTP/3 使用 UDP
简单邮件传送协议 SMTP 25 TCP
邮件读取协议 POP3 110 TCP
网际报文存取协议 IMAP 143 TCP

Web 页面请求过程

在浏览器中输入 https://www.example.com/ 并回车后,主要经过以下步骤:

  1. 浏览器解析 URL,得到协议 https、主机名 www.example.com、端口(省略时 https 为 443)和路径 /,各部分的含义见 URL,然后检查缓存,有未过期的缓存时直接使用,见 缓存;
  2. DNS 解析主机名 www.example.com,得到 IP 地址,路径和参数不参与解析;
  3. 与服务器进行 TCP 三次握手,HTTPS 还要进行 TLS 握手;
  4. 发送 HTTP 请求。请求通常先到达负载均衡或反向代理(例如 Nginx),再转发给某台应用服务器,应用服务器查询缓存或数据库后生成响应。如果响应是重定向,例如访问 baidu.com 得到 301 和 Location: https://www.baidu.com/(见附录 A3),浏览器对新地址重新走一遍前面的步骤;
  5. 浏览器解析 HTML 构建 DOM 树,解析 CSS 构建 CSSOM,两者合成渲染树,再计算每个元素的位置和大小(布局),最后绘制到屏幕上。解析中遇到 CSS、JavaScript、图片等外部资源时另发请求(HTTP/2 下同一服务器上的资源可以在一个连接上并发请求,见 HTTP/2.0),不带 async 或 defer 的普通脚本(type 不是 module)会暂停 HTML 的解析,直到脚本下载并执行完;
  6. 连接保持一段时间供后续请求复用,空闲后关闭,见 短连接与长连接。

只输入 baidu.com 这类不带协议的地址时,现在的 Chrome、Firefox 和 iOS 上的 Safari 先补上 https 访问,连接失败才退回 http。域名在浏览器的 HSTS 记录或预加载列表中时,输入的 http 地址在浏览器内部就改为 https,不会发出明文请求,也不会退回 http,见 HTTPS 中关于 HSTS 的一段。

以下是访问该网址时各阶段的耗时(curl 实测,见附录 A1):

Web 页面请求过程的配图

从网络各层看,一台刚接入局域网的主机要发出这个请求,先后要用到 DHCP、ARP、DNS、TCP 和 TLS。下图是它依次发出的前几个帧,下面逐步说明:

Web 页面请求过程的配图

1. DHCP 配置主机信息

2. ARP 解析 MAC 地址

3. DNS 解析域名

4. HTTP 请求页面

附录:实测

A1 访问网页各阶段的耗时

macOS 自带的 curl,网络的 RTT 约 200 ms,连续访问 3 次。各字段都是从开始到该阶段结束的累计时间:time_connect 为 TCP 连接建立,time_appconnect 为 TLS 握手完成,time_starttransfer 为收到响应的第一个字节。第 3 次的 TLS 握手明显变慢,属于网络波动,配图使用第 1 次的结果:

$ curl -s -o /dev/null -w 'namelookup %{time_namelookup}  connect %{time_connect}  appconnect %{time_appconnect}  starttransfer %{time_starttransfer}  total %{time_total}  http %{http_version}\n' https://www.example.com/
namelookup 0.001929  connect 0.202011  appconnect 0.411088  starttransfer 0.619656  total 0.620218  http 2
namelookup 0.004086  connect 0.209781  appconnect 0.432419  starttransfer 0.650939  total 0.651432  http 2
namelookup 0.001873  connect 0.216569  appconnect 1.441755  starttransfer 1.667668  total 1.668500  http 2

A2 DNS 的 TTL 与 CNAME

macOS 自带的 dig 9.10.6,先向公共 DNS 223.5.5.5 查询两次,间隔 5 秒,再不经递归直接询问京东的权威服务器 ns1.jd.com:

$ dig @223.5.5.5 www.jd.com +noall +answer
www.jd.com.        74    IN    CNAME    www.jd.com.gslb.qianxun.com.
www.jd.com.gslb.qianxun.com. 11    IN    CNAME    www.jd.com.s.galileo.jcloud-cdn.com.
www.jd.com.s.galileo.jcloud-cdn.com. 20    IN CNAME wwwv6.jcloudimg.com.
wwwv6.jcloudimg.com.    15    IN    A    119.147.159.135

$ (5 秒后)dig @223.5.5.5 www.jd.com +noall +answer
www.jd.com.        69    IN    CNAME    www.jd.com.gslb.qianxun.com.
www.jd.com.gslb.qianxun.com. 6    IN    CNAME    www.jd.com.s.galileo.jcloud-cdn.com.
www.jd.com.s.galileo.jcloud-cdn.com. 15    IN CNAME wwwv6.jcloudimg.com.
wwwv6.jcloudimg.com.    10    IN    A    119.147.159.135

$ dig @ns1.jd.com www.jd.com +noall +answer +norecurse
www.jd.com.        120    IN    CNAME    www.jd.com.gslb.qianxun.com.
www.jd.com.gslb.qianxun.com. 60    IN    CNAME    www.jd.com.s.galileo.jcloud-cdn.com.

A3 省略协议时的重定向

macOS 自带的 curl 8.7.1,2026-10-30 分别以 http 和 https 访问 baidu.com,只显示状态行和 Location 首部:

$ curl -s -D - -o /dev/null http://baidu.com | grep -iE '^HTTP|^location'
HTTP/1.1 301 Moved Permanently
Location: https://www.baidu.com/

$ curl -s -D - -o /dev/null https://baidu.com | grep -iE '^HTTP|^location'
HTTP/1.1 301 Moved Permanently
Location: https://www.baidu.com/

参考资料

在阅读器中可以用目录和搜索、切换深色模式、练习这篇笔记中的面试题:打开《计算机网络 - 应用层》