面试通关计算机网络--键入网址到网页显示,期间发生了什么?

阶段一:用户操作与浏览器初步处理 (应用层)

  1. 用户输入URL: 你在浏览器地址栏输入一个网址,比如 http://www.example.com/index.html​,然后按下回车。

  2. URL解析:

    • 浏览器首先会解析这个URL,提取出关键信息:

      • 协议 (Protocol): http​ (表明使用HTTP协议)
      • 域名 (Domain Name): www.example.com​ (需要访问的服务器的名称)
      • 路径 (Path): /index.html​ (请求服务器上的具体资源/文件)
      • 如果URL中还包含端口号 (如 http://www.example.com:8080​),也会被解析出来。HTTP默认端口是80,HTTPS是443。如果省略,则使用默认端口。
    • 如你笔记中提到的,如果路径部分省略 (如只输入 www.example.com​),浏览器通常会请求服务器根目录下的默认文件(如 index.html​ 或 default.html​)。

  3. 检查浏览器缓存 (DNS及页面缓存):

    • 浏览器会先检查自己的缓存中是否有这个域名对应的IP地址 (DNS缓存)。
    • 同时,浏览器也会检查是否有该URL的页面缓存 (HTTP缓存),如果缓存有效且未过期,可能会直接从缓存中加载页面,这个过程就大大简化了。但我们这里讨论完整流程,假设缓存未命中或已过期。
  4. 构建HTTP请求报文:

    • 浏览器确定了要请求的资源和服务器后,会构建一个HTTP请求报文。

    • 典型的HTTP请求报文包含:

      • 请求行 (Request Line): 例如 GET /index.html HTTP/1.1​ (方法、请求的URI、HTTP协议版本)
      • 请求头 (Request Headers): 包含一系列键值对,如 Host: www.example.com​, User-Agent: Mozilla/5.0 ...​, Accept: text/html​, Connection: keep-alive​ 等,提供了关于客户端和请求的附加信息。
      • 请求体 (Request Body): 对于GET请求通常为空。对于POST等请求,会包含要发送给服务器的数据。
    • 正如你的笔记所说,这个“孤单小弟HTTP”数据包准备好了,但它不知道该往哪里去。

阶段二:域名解析为IP地址 (应用层 - DNS)

  1. DNS查询:

    • HTTP请求需要发送到目标服务器,但这需要目标服务器的IP地址,而不是域名。因此,操作系统会发起DNS查询。

    • 查询顺序 (涉及多级缓存),正如你笔记中详细描述的:

      1. 浏览器缓存: 浏览器自身查看有无该域名的DNS缓存。
      2. 操作系统缓存: 若浏览器缓存未命中,查询操作系统的DNS缓存。
      3. Hosts文件: 操作系统查看本地的 hosts​ 文件是否有该域名的静态配置。
      4. 本地DNS服务器 (LDNS): 如果以上均未命中,操作系统会将DNS查询请求发送给在网络配置中指定的本地DNS服务器(通常由你的ISP提供,或者你手动配置的如Google的 8.8.8.8​)。
    • 本地DNS服务器的解析过程 (递归或迭代查询):

      在域名中,越靠右的位置表示其层级越高。

      1. LDNS收到请求后,先查自己的缓存。
      2. 若LDNS缓存未命中,它会向根DNS服务器发起查询。根服务器不会直接给出IP,而是告诉LDNS管理 .com​ (或其他顶级域) 的顶级域DNS服务器 (TLD DNS Server) 的地址。
      3. LDNS再向TLD DNS服务器查询。TLD DNS服务器会告诉LDNS负责 example.com​ 这个域名的权威DNS服务器 (Authoritative DNS Server) 的地址。
      4. LDNS最终向权威DNS服务器查询 www.example.com​ 的IP地址。权威DNS服务器拥有该域名的最终解析记录。
      5. 权威DNS服务器将IP地址返回给LDNS。
      6. LDNS将IP地址返回给操作系统,并缓存该记录以备后续查询。
    • 操作系统得到IP地址后,将其返回给浏览器。

阶段三:建立TCP连接 (传输层)

  1. TCP三次握手:

    • HTTP协议通常基于可靠的TCP协议进行传输。在发送HTTP请求之前,浏览器(客户端)需要与服务器(通过上一步获得的IP地址和HTTP默认端口80或HTTPS的443)建立TCP连接。

    • 这个过程就是著名的三次握手:

      1. SYN (同步序列编号): 客户端发送一个TCP段,其中SYN标志位置1,并选择一个初始序列号 (client_isn)。客户端进入 SYN-SENT​ 状态。
      2. SYN+ACK (同步确认): 服务器收到SYN后,如果同意连接,则回复一个TCP段,其中SYN和ACK标志位都置1,确认号 (ack) 设置为 client_isn + 1​,并选择自己的初始序列号 (server_isn)。服务器进入 SYN-RCVD​ 状态。
      3. ACK (确认): 客户端收到服务器的SYN+ACK后,发送一个ACK段,其中ACK标志位置1,确认号 (ack) 设置为 server_isn + 1​。客户端进入 ESTABLISHED​ 状态。服务器收到这个ACK后,也进入 ESTABLISHED​ 状态。
    • 三次握手的目的是同步双方的初始序列号,并确认双方都具有收发数据的能力。

阶段四:数据在协议栈中的封装与发送 (传输层、网络层、数据链路层、物理层)

现在,HTTP请求报文准备好了,TCP连接也建立了,数据要开始真正的旅程了。

  1. 应用层数据交给传输层: 浏览器将HTTP请求报文交给操作系统的协议栈中的TCP模块。

  2. 传输层封装 (TCP段):

    • TCP模块为HTTP报文添加TCP头部,形成TCP段 (TCP Segment)。
    • TCP头部包含:源端口号(浏览器随机分配的临时端口)、目标端口号(Web服务器的80或443端口)、序列号、确认号、窗口大小、各种标志位等。
    • 如果HTTP报文过大,超过了MSS (Maximum Segment Size),TCP会将其分割成多个TCP段。
  3. 网络层封装 (IP包):

    • TCP段被交给IP模块。IP模块为其添加IP头部,形成IP数据包 (IP Packet)。

    • IP头部包含:源IP地址(客户端IP)、目标IP地址(服务器IP)、协议号(指明上层是TCP,值为6)等。

    • 选择源IP地址和出口网卡: 如果客户端有多个网卡(多个IP地址),操作系统会根据路由表和目标IP地址来决定使用哪个网卡的IP作为源IP,以及从哪个物理接口发送出去。

      • 路由表匹配规则:将目标IP与路由表中各条目的子网掩码进行“与”运算,看结果是否与该条目的目标网络地址匹配。如果有多条匹配,通常选择最长前缀匹配的条目。如果没有特定匹配,则走默认网关。
  4. 数据链路层封装 (以太网帧):

    • IP数据包被交给网络接口层(例如以太网驱动程序)。它会为IP包添加以太网帧头和帧尾,形成以太网帧 (Ethernet Frame)。

    • 帧头包含:目标MAC地址和源MAC地址,以及类型字段(指明上层是IP协议,值为 0x0800​)。

    • 帧尾包含:帧校验序列 (FCS),用于差错检测。

    • 确定目标MAC地址 (ARP):

      • 情况1:目标服务器与客户端在同一子网:客户端需要目标服务器的MAC地址。它会先检查自己的ARP缓存表。如果有缓存,直接使用。如果没有,客户端会发送一个ARP广播请求:“谁的IP是 [服务器IP]?请告诉我你的MAC地址。” 同一子网内的目标服务器收到后会单播回复其MAC地址。客户端收到后更新ARP缓存。
      • 情况2:目标服务器与客户端不在同一子网:数据包需要发送给默认网关 (路由器)。客户端需要默认网关的MAC地址。同样,先查ARP缓存,没有则发送ARP广播请求:“谁的IP是 [默认网关IP]?请告诉我你的MAC地址。” 默认网关回复其MAC地址。
      • 关键点:此时,以太网帧中的目标MAC地址是下一跳设备(同一子网的服务器,或默认网关)的MAC地址,而IP包中的目标IP地址始终是最终Web服务器的IP地址。
  5. 物理层传输:

    • 网卡将以太网帧转换成电信号(或光信号),通过物理介质(网线、光纤、无线电波)发送出去。

阶段五:数据包在网络中的传输 (路由器与交换机)

  1. 交换机 (二层设备):

    • 数据帧到达本地网络的交换机。

    • 交换机工作在数据链路层。它查看帧的目标MAC地址。

    • 交换机维护一个MAC地址表(MAC地址与端口的映射关系)。

      • 如果目标MAC地址在表中,交换机直接从对应的端口将帧转发出去。
      • 如果目标MAC地址不在表中,或者目标MAC是广播地址 (FF:FF:FF:FF:FF:FF),交换机会将帧从除了接收端口外的所有其他端口泛洪 (flood) 出去。
      • 交换机通过学习源MAC地址来构建和更新其MAC地址表(“这个MAC地址是从哪个端口进来的”)。
    • 交换机不改变帧的内容,原样转发。它没有IP地址和MAC地址的概念(指其端口)。

  2. 路由器 (三层设备):

    • 如果数据包的目的地不在本地子网,它会被发送到默认网关——路由器。

    • 路由器工作在网络层。它的每个端口都有自己的MAC地址和IP地址。

    • 接收操作: 路由器端口接收到以太网帧,检查目标MAC地址是否是自己的端口MAC。如果是,则接收该帧,并去掉帧头帧尾,暴露出IP包。

    • 路由决策: 路由器查看IP包的目标IP地址,并查询其路由表。

      • 路由表包含:目标网络地址、子网掩码、下一跳IP地址(Next Hop)、出接口(Interface)。
      • 路由器根据目标IP地址匹配路由表条目,找到数据包应该从哪个接口转发出去,以及下一跳路由器的IP地址是什么。如果没有精确匹配,则走默认路由。
    • 重写MAC头部 (关键步骤): 路由器确定了下一跳后,需要为IP包重新封装一个新的以太网帧头。

      • 新的帧头中,源MAC地址是路由器发送端口的MAC地址。
      • 目标MAC地址是下一跳路由器(或最终目标主机,如果下一跳就是目标且在同一链路)的MAC地址。这个MAC地址同样通过ARP协议(查询ARP缓存或发送ARP请求)获得。
      • IP包头中的源IP和目标IP地址在整个路由过程中保持不变!
    • 发送操作: 新的帧通过物理层发送出去。

    • 这个过程(解封装、查路由表、重新封装、发送)会在每一跳路由器上重复,直到数据包到达目标服务器所在的网络。

阶段六:服务器处理请求并返回响应 (应用层、传输层等)

  1. 服务器接收数据包: 数据包最终到达目标Web服务器。

    • 服务器的网卡接收以太网帧,物理层转为数字信号。
    • 数据链路层检查目标MAC地址,是自己的,去掉帧头帧尾,交给网络层。
    • 网络层检查目标IP地址,是自己的,去掉IP头部,根据协议号(TCP)交给传输层。
    • 传输层检查目标端口号(如80),发现是HTTP服务在监听,去掉TCP头部,将HTTP请求报文交给Web服务器应用程序(如Nginx, Apache)。
  2. Web服务器处理请求:

    • Web服务器解析HTTP请求报文。
    • 根据请求的资源(如 /index.html​),从服务器的磁盘或其他地方获取内容。
    • 可能涉及到后端逻辑处理(如数据库查询、动态页面生成等)。
  3. 构建HTTP响应报文:

    • 服务器构建一个HTTP响应报文。

    • 典型的HTTP响应报文包含:

      • 状态行 (Status Line): 例如 HTTP/1.1 200 OK​ (协议版本、状态码、状态描述)
      • 响应头 (Response Headers): 如 Content-Type: text/html​, Content-Length: 1234​, Server: Apache​ 等。
      • 响应体 (Response Body): 实际的网页内容 (HTML, CSS, JavaScript, 图片等)。
  4. 服务器发送响应:

    • 这个HTTP响应报文会经历与客户端发送请求时类似的封装过程(TCP封装 -> IP封装 -> 以太网帧封装),但这次源IP/端口是服务器的,目标IP/端口是客户端的。
    • 响应数据包通过互联网,经过路由器逐跳转发,最终到达客户端所在的网络。

阶段七:客户端接收并渲染页面 (物理层到应用层)

  1. 客户端接收数据包: 客户端的网卡接收到来自服务器的响应数据包。

    • 经历与服务器接收时类似的解封装过程:物理层 -> 数据链路层 (检查MAC) -> 网络层 (检查IP) -> 传输层 (检查端口,重组TCP段) -> 将HTTP响应报文交给浏览器。
  2. 浏览器解析并渲染页面:

    • 浏览器接收到HTTP响应报文。
    • 解析HTTP响应头,根据 Content-Type​ 等信息知道如何处理响应体(例如,作为HTML文档)。
    • 解析HTML: 构建DOM (Document Object Model) 树。
    • 解析CSS: 构建CSSOM (CSS Object Model) 树。
    • 合并DOM和CSSOM: 构建渲染树 (Render Tree)。
    • 布局 (Layout/Reflow): 计算每个节点在屏幕上的确切位置和大小。
    • 绘制 (Paint): 将渲染树的节点绘制到屏幕上。
    • 处理页面中的其他资源: 如果HTML中包含其他资源(如CSS文件、JavaScript文件、图片),浏览器会针对每一个资源重复上述大部分过程(发起新的HTTP请求 -> DNS查询 -> TCP连接 -> ... -> 下载资源 -> 解析/执行)。这通常是并发进行的。
    • 执行JavaScript: JS可能会修改DOM和CSSOM,导致重新布局和绘制。

阶段八:TCP连接关闭 (传输层)

  1. TCP四次挥手: 当数据传输完毕(例如浏览器认为页面加载完成,或者一方决定关闭连接),会进行TCP的四次挥手来断开连接。

    • 假设客户端发起关闭:

      1. FIN: 客户端发送一个FIN段,表示数据发送完毕。客户端进入 FIN-WAIT-1​ 状态。
      2. ACK: 服务器收到FIN后,回复一个ACK段作为确认。服务器进入 CLOSE-WAIT​ 状态。客户端收到ACK后进入 FIN-WAIT-2​ 状态。此时,从客户端到服务器方向的连接关闭,但服务器可能还有数据要发送给客户端。
      3. FIN: 当服务器也没有数据要发送时,服务器发送一个FIN段给客户端。服务器进入 LAST-ACK​ 状态。
      4. ACK: 客户端收到服务器的FIN后,回复一个ACK段。客户端进入 TIME-WAIT​ 状态(等待一段时间确保服务器收到ACK,防止已失效的请求报文段出现在本连接中)。服务器收到ACK后进入 CLOSED​ 状态。客户端等待 2MSL​ (Maximum Segment Lifetime,报文最大生存时间的两倍) 后,也进入 CLOSED​ 状态。

至此,从键入网址到网页显示的整个主要流程就完成了。这是一个极其精妙和复杂的协作过程!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值