上网这件事对于现时代年轻人来说已经是家常便饭了,那么当输入一个URL(网址)之后会发生什么呢?这里面涉及到计算机图形学、操作系统、编译原理、计算机网络、通信原理、分布式系统、浏览器原理等多个不同的学科、领域。在这里由于我的能力和知识都有限,只能大概讲述我认知中的事情
大致会发生下面这些事情:
- DNS解析域名
- 建立连接
- 发送HTTP请求
- TCP/IP协议封装和分用
- 返回HTTP响应
- 浏览器解析
- 断开连接
一、DNS解析
首先,浏览器向本地DNS服务器发起请求,如果本地有缓存,就直接能找到域名对应的IP地址,如果没找到就需要采用递归或者迭代查询的方式依次向根域名服务器、顶级域名服务器、权威域名服务器发起查询请求,直至找到一个或一组 IP 地址,返回给浏览器。
二、建立连接
三次握手建立连接的目的是为了确认通信双方的接收和发送能力是否正常。
- 在连接建立之前,服务器必须做好接受连接的准备,通过调用 socket、bind、listen 和 accept 四个函数来完成绑定公网 IP、监听 443 端口和接受请求的任务。
- 客户端通过 socket 和 connect 两个函数来主动打开连接,给服务器发送带有 SYN 标志位的分组,随机生成一个初始序列号 x,以及附带 MSS(Maximum Segment Size,最大段大小)等额外信息。为了避免在网络层被 IP 协议分片使得出现丢失错误的概率增加,及达到最佳的传输效果,MSS 的值一般为以太网 MTU(Maximum Transmission Unit,最大传输单元)的值减去 IP 头部和 TCP 头部大小,等于 1460 字节
- 服务器必须确认收到客户端的分组,发送带有 SYN+ACK 标志位的分组,随机生成一个初始序列号 y,确认号为 x+1,以及附带 MSS 等额外信息。当一端收到另外一端的 MSS 值时,会根据两者的 MSS 取最小值来决定随后的 TCP 最大报文段大小
- 客户端确认收到服务器的分组,发送带有 ACK 标志位的分组,确认号为 y+1,从而建立 TCP 连接
三、发送HTTP请求
连接建立好之后,HTTP协议会根据输入的URL构造出一个HTTP请求,其中包括请求行、请求报头、空行、请求正文四部分,请求行中包括方法、URL、版本号三个部分,请求报头中是一些键值对形式的属性,空行代表请求头的结束,请求正文里包含发送的数据,一般GET方法没有请求正文部分。
四、TCP/IP协议栈的封装和分用
HTTP协议构造好一个数据报之后交给传输层协议,TCP协议会在数据前加上一个TCP头部,然后再向下交给网络层,网络层在前面再加上一个IP头部,再向下交给数据链路层,加上以太网数据帧头和帧尾,最后通过物理层发送给服务器,服务器接收到数据后,对数据依次进行分用,应用层拿到发来的HTTP请求后,对其中信息进行解析,然后构造出一个HTTP响应再经过TCP/IP协议栈发送回去。
五、返回HTTP响应
HTTP响应的格式和请求类似,是由首行、响应报头、空行、响应正文组成的,首行略微和请求有区别,由版本号、状态码、和状态描述组成,根据状态码客户端可以知道这次的请求是成功了还是失败了。
六、浏览器解析
一般服务器返回都是一个HTML文件,浏览器接收到这个文件后,通过分析,会再向服务器请求HTML中确实的标签,比如CSS文件或者JS文件等,然后通过一系列操作,把页面显示出来。
七、断开连接
断开连接可以由客户端发起也可以由服务器发起
- 服务器通过调用 close 函数主动关闭连接,向客户端发送带有 FIN 标志位的分组,序列号为 m
- 客户端确认收到该分组,向服务器发送带有 ACK 标志位的分组,确认号为 m+1
- 客户端发送完所有数据后,向服务器发送带有 FIN 标志位的分组,序列号为 n
- 服务器确认收到该分组,向客户端发送带有 ACK 标志位的分组,序列号为 n+1。客户端收到确认分组后,立即进入 CLOSED 状态;同时,服务器等待 2 个 MSL(Maximum Segment Lifetime,最大报文生存时间) 的时间后,进入 CLOSED 状态
总结
总之上网这件事内部的实现是非常复杂的,这里只是简单的讲述了一些大概流程,其中具体的细节是非常非常多的,只是这些细节都由浏览器帮我们处理了。
|