本文的步骤是建立在,请求的是一个简单的 HTTP 请求,没有 HTTPS、HTTP2、最简单的 DNS、没有代理、并且服务器没有任何问题的基础上,尽管这是不切实际的。
首先我们会一个个字母去敲击键盘打出来,然后屏幕显示到浏览器的输出框里,那这个是怎么实现的?
我们先来看看 CPU 的硬件架构图:
CPU 里面的内存接口,直接和系统总线通信,然后系统总线再接入一个 I/O 桥接器,这个 I/O 桥接器,另一边接入了内存总线,使得 CPU 和内存通信。再另一边,又接入了一个 I/O 总线,用来连接 I/O 设备,比如键盘、显示器等。
那当用户输入了键盘字符,键盘控制器就会产生扫描码数据,并将其缓冲在键盘控制器的寄存器中,紧接着键盘控制器通过总线给 CPU 发送中断请求。
CPU 收到中断请求后,操作系统会保存被中断进程的 CPU 上下文,然后调用键盘的中断处理程序。
键盘的中断处理程序是在键盘驱动程序初始化时注册的,那键盘中断处理函数的功能就是从键盘控制器的寄存器的缓冲区读取扫描码,再根据扫描码找到用户在键盘输入的字符,如果输入的字符是显示字符,那就会把扫描码翻译成对应显示字符的 ASCII 码,比如用户在键盘输入的是字母 A,是显示字符,于是就会把扫描码翻译成 A 字符的 ASCII 码。
得到了显示字符的 ASCII 码后,就会把 ASCII 码放到「读缓冲区队列」,接下来就是要把显示字符显示屏幕了,显示设备的驱动程序会定时从「读缓冲区队列」读取数据放到「写缓冲区队列」,最后把「写缓冲区队列」的数据一个一个写入到显示设备的控制器的寄存器中的数据缓冲区,最后将这些数据显示在屏幕里。
显示出结果后,恢复被中断进程的上下文。
url敲完之后,我们需要按下回车键来进行http的访问,还是靠中断请求来让cpu处理这个访问请求。
首先浏览器程序会去解析url:
解析url完之后,如果不是纯ip就会进行dns域名解析,在网络中定位是依靠 ip进行身份定位的,所以 url 访问的第一步便是先要得到服务器端的 ip 地址。而得到服务器的 ip 地址需要使用 dns(Domain Name System,域名系统)域名解析,dns 域名解析就是通过 url 找到与之相对应的 ip 地址。当然这也是有基本的步骤的:
在拿到对应的ip地址后,会以随机端口(1024~~65535)向web服务器程序80端口发起tcp的连接请求,这个连接请求进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达web程序,最终建立了TCP/IP的连接,对于客户端与服务器的TCP链接,就是tcp三次握手。
建立tcp连接之后,组装http报文并发起http请求(一般在第三次握手时就可以携带期望传输的报文了),然后就得经历层层封装与解封来传输报文了(上面的tcp握手一样是这么传递报文的)。
web服务器端收到请求后解析用户请求,然后经过逻辑处理最后将响应数据通过web服务器返回给浏览器客户端。
当浏览器拿到响应数据后,为了避免服务器与客户端双方的资源占用和损耗,根据请求头的Connection的值或者是其他方式,任意一方都可以发起关闭tcp连接,也就是进行tcp四次挥手。
若Connection 的值为close,则服务器主动关闭tcp连接,客户端被动关闭连接,释放tcp连接。若Connection 为keep-alive,则该连接会保持一段时间,在该时间内可以继续处理任何请求。
如果相应数据为非html文件,浏览器会帮忙做成html文件,也就是在数据外面嵌套一层html。然后就开始渲染界面,浏览器是一个边解析边渲染的过程: