输入网址后发生了什么???操作系统

今天有位小伙伴在论坛里说面试问这个问题,那他的回答是:

  • 客户端通过DNS解析域名得到服务器IP地址 
  • 客户端向服务器TCP连接请求,通过TCP三次握手建立socket连接 
  • 建立连接后,客户端发起一个http请求获取网页内容 
  • 网络层进行ip寻址,数据链路层封装成帧,物理层的利用物理介质传输 
  • 服务器收到请求后调用自身服务处理请求并返回http响应包 
  • 关闭TCP连接 
  • 客户端收到服务器响应内容后就开始渲染页面

哎哟喂?这不就是我辛辛苦苦准备的答案么?网上博客到的答案?在这里,我要diss一些所谓的“大牛”博客主,你写的东西就是垃圾,你抄我,我抄你,你自己写的东西都不看,然后误导别人,流下的愤青的泪水,这。。。。不扯了,看看到底怎么回答才对

按下“ g”键

以下各节说明了物理键盘操作和操作系统中断。当您按下键“ g”时,浏览器会接收到该事件,并且自动完成功能会启动。根据浏览器的算法以及您是否处于私密/隐身模式,是否会在下方的下拉菜单中为您提供各种建议网址栏。这些算法大多数都基于整个网络中的搜索历史,书签,Cookie和热门搜索对结果进行排序和优先级排序。在您输入“ google.com”时,会运行许多代码块,并且每次按键都会完善建议。在您完成输入之前,它甚至可能会建议“ google.com”。

“输入”键触底

要选择零点,让我们选择键盘上敲击范围底部的Enter键。此时,回车键专用的电路(直接或电容性)闭合。在这种情况下,这允许少量电流流入键盘的逻辑电路,该逻辑电路扫描每个键开关的状态,消除快速间歇性闭合开关的电噪声,并将其转换为键码整数13.然后,键盘控制器对键码进行编码,以传输到计算机。现在,这几乎普遍通过通用串行总线(USB)或蓝牙连接进行,但历史上一直通过PS / 2或ADB连接进行。

对于USB键盘:

  • 键盘的USB电路由计算机USB主机控制器通过针1提供的5V电源供电。
  • 生成的键码由内部键盘电路存储器存储在称为“端点”的寄存器中。
  • 主机USB控制器每隔约10毫秒(由键盘声明的最小值)轮询一次“端点”,因此它将获取存储在其上的键码值。
  • 该值进入USB SIE(串行接口引擎),以转换为遵循低级USB协议的一个或多个USB数据包。
  • 这些数据包通过D +和D-引脚(中间2个)上的差分电信号以最大1.5 Mb / s的速度发送,因为HID(人机接口设备)设备始终被声明为“低速设备”。 (符合USB 2.0)。
  • 然后,该串行信号在计算机的主机USB控制器上解码,并由计算机的人机接口设备(HID)通用键盘设备驱动程序进行解释。然后将密钥的值传递到操作系统的硬件抽象层。

对于虚拟键盘(如在触摸屏设备中):

  • 当用户将手指放在现代电容式触摸屏上时,少量电流会转移到手指上。这通过导电层的静电场完成了电路,并在屏幕上的该点产生了电压降。在 screen controller随后引发中断报告按键的坐标。
  • 然后,移动操作系统会在其GUI元素之一(现在是虚拟键盘应用程序按钮)中向当前关注的应用程序通知按下事件。
  • 虚拟键盘现在可以引发软件中断,以将“按键被按下”消息发送回操作系统。
  • 该中断通知当前关注的应用程序“按键”事件。

中断触发[不适用于USB键盘]

键盘在其中断请求线(IRQ)上发送信号,该中断请求线interrupt vector由中断控制器映射到(整数)。CPU使用Interrupt Descriptor Table(IDT)将中断向量映射到interrupt handlers内核提供的函数()。当中断到达时,CPU用中断向量索引IDT并运行适当的处​​理程序。这样就进入了内核。

(在Windows上)一条WM_KEYDOWN消息发送到该应用程序

HID传输将密钥按下事件传递给KBDHID.sys驱动程序,该驱动程序将HID用法转换为扫描代码。在这种情况下,扫描代码为 VK_RETURN0x0D)。该KBDHID.sys驱动程序与KBDCLASS.sys(键盘类驱动程序)接口 。该驱动程序负责以安全的方式处理所有键盘和小键盘输入。然后,它调用 Win32K.sys(可能在将消息通过安装的第三方键盘过滤器传递之后)。这一切都发生在内核模式下。

Win32K.sys通过GetForegroundWindow()API 找出哪个窗口是活动窗口 。该API提供了浏览器地址框的窗口句柄。然后,主Windows“消息泵”会调用 SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam)lParam是一个位掩码,指示有关按键的更多信息:重复计数(在这种情况下为0),实际扫描代码(可以取决于OEM,但通常不用于VK_RETURN),是否扩展键(例如alt,shift,ctrl)也被按下(没有),以及其他一些状态。

Windows SendMessageAPI是一种简单易用的功能,可将消息添加到特定窗口句柄(hWnd)的队列中。稍后,将调用WindowProc分配给的主要消息处理功能(称为)hWnd以处理队列中的每个消息。

hWnd处于活动状态的窗口()实际上是一个编辑控件, WindowProc在这种情况下,它具有消息的消息处理程序WM_KEYDOWN。该代码在传递给SendMessage (wParam)的第3个参数内查找,因为它VK_RETURN知道用户已按ENTER键。

(在OS X上)KeyDownNSEvent发送到应用程序

中断信号在I / O Kit kext键盘驱动程序中触发一个中断事件。驱动程序将信号转换为键码,然后传递给OS X WindowServer进程。结果,WindowServer分派事件通过它们的Mach端口将事件分配到任何适当的应用程序(例如,活动或监听),并将其放入事件队列中。然后,具有足够特权的线程可以调用此mach_ipc_dispatch函数从该队列中读取事件 。这最常发生通过,并且由一个处理NSApplication主事件循环通过,NSEvent的 NSEventType KeyDown

(在GNU / Linux上)Xorg服务器侦听密钥代码

当使用图形时X serverX将使用通用事件驱动程序evdev来获取按键。使用X server特定的键映射和规则将键代码重新映射为扫描代码。按下键的扫描代码映射完成后,X server 会将字符发送到window manager(DWM,metacity,i3等),因此 window manager依次将字符发送到焦点窗口。接收字符的窗口的图形API在适当的焦点字段中打印适当的字体符号。

解析网址

  • 现在,浏览器在URL(统一资源定位器)中包含以下信息:

    • Protocol “ http”

      使用“超文本传输​​协议”

    • Resource “ /”

      检索主(索引)页面

是URL还是搜索词?

如果未提供协议或有效域名,浏览器将继续将地址栏中提供的文本输入浏览器的默认网络搜索引擎。在许多情况下,URL后面会附加一段特殊的文字,以告诉搜索引擎它来自特定浏览器的URL栏。

转换主机名中的非ASCII Unicode字符

  • 浏览器检查,在没有主机名的人物a-z, A-Z0-9-,或.
  • 由于主机名google.com不存在,因此如果没有,浏览器会将Punycode编码应用于URL的主机名部分。

查看HSTS清单

  • 浏览器检查其“预加载的HSTS(HTTP严格传输安全性)”列表。这是请求仅通过HTTPS与之联系的网站的列表。
  • 如果网站在列表中,则浏览器通过HTTPS而不是HTTP发送请求。否则,初始请求将通过HTTP发送。(请注意,网站仍可以使用HSTS策略,不会出现在HSTS列表中。用户向网站提出的第一个HTTP请求将收到响应,要求用户仅发送HTTPS请求。但是,此单个HTTP请求可能会离开用户容易遭受 降级攻击,这就是为什么HSTS列表包含在现代Web浏览器中的原因。)

DNS查询

  • 浏览器检查域是否在其缓存中。(要查看Chrome中的DNS缓存,请访问chrome:// net-internals /#dns)。
  • 如果未找到,浏览器将调用gethostbyname库函数(因操作系统而异)进行查找。
  • gethostbyname在尝试通过DNS解析主机名之前,检查主机名是否可以通过本地hosts文件中的引用解析(其位置因OS而异)。
  • 如果gethostbyname没有缓存它,也无法在hosts 文件中找到它,那么它将向网络堆栈中配置的DNS服务器发出请求。这通常是本地路由器或ISP的缓存DNS服务器。
  • 如果DNS服务器在同一子网中,则网络库遵循 ARP process以下DNS服务器。
  • 如果DNS服务器位于其他子网中,则网络库将遵循ARP process以下默认网关IP。

ARP过程

为了发送ARP(地址解析协议)广播,网络堆栈库需要目标IP地址进行查找。它还需要知道用于发送ARP广播的接口的MAC地址。

首先检查ARP缓存中是否有目标IP的ARP条目。如果它在高速缓存中,则库函数返回结果:目标IP = MAC。

如果该条目不在ARP缓存中:

  • 查找路由表,以查看目标IP地址是否在本地路由表的任何子网中。如果是,则库使用与该子网关联的接口。如果不是,则库使用具有默认网关子网的接口。
  • 查找所选网络接口的MAC地址。
  • 网络库发送第2层(OSI模型的数据链路层)ARP请求:

ARP Request

发件人MAC:接口:mac:地址:此处
发件人IP:interface.ip.goes.here
目标MAC:FF:FF:FF:FF:FF:FF(广播)
目标IP:target.ip.goes.here

根据计算机和路由器之间的硬件类型:

直接连接:

  • 如果计算机直接连接到路由器,则路由器会以回应ARP Reply(请参阅下文)

毂:

  • 如果计算机连接到集线器,则集线器将在所有其他端口上广播ARP请求。如果路由器连接在同一条“电线”上,它将以回应ARP Reply(见下文)。

开关:

  • 如果计算机连接到交换机,则该交换机将检查其本地CAM / MAC表,以查看哪个端口具有我们要查找的MAC地址。如果交换机没有MAC地址条目,它将把ARP请求重新广播到所有其他端口。
  • 如果交换机在MAC / CAM表中有一个条目,它将把ARP请求发送到具有我们要查找的MAC地址的端口。
  • 如果路由器在同一条“电线”上,它将以回应ARP Reply (见下文)

ARP Reply

发件人MAC:target:mac:address:here
发件人IP:target.ip.goes.here
目标MAC:接口:mac:地址:此处
目标IP:interface.ip.goes.here

现在,网络库具有我们的DNS服务器或默认网关的IP地址,它可以恢复其DNS进程:

  • DNS客户端使用1023以上的源端口在DNS服务器上的UDP端口53上建立套接字。
  • 如果响应大小太大,则将使用TCP。
  • 如果本地/ ISP DNS服务器没有该服务器,则将请求递归搜索,该搜索将沿DNS服务器列表向上流动,直到到达SOA,如果找到,则返回答案。

打开插座

一旦浏览器收到目标服务器的IP地址,它将从URL获取该地址和给定的端口号(HTTP协议默认为端口80,HTTPS为端口443),并调用名为socket和的系统库函数。请求一个TCP套接字流- AF_INET/AF_INET6和 SOCK_STREAM

  • 该请求首先传递到传输层,在传输层中制作TCP段。将目标端口添加到标头,并从内核的动态端口范围(在Linux中为ip_local_port_range)内选择源端口。
  • 该段被发送到网络层,该网络层包装了一个附加的IP标头。插入目标服务器的IP地址以及当前计算机的IP地址以形成一个数据包。
  • 数据包接下来到达链路层。添加了一个帧头,其中包括机器NIC的MAC地址以及网关(本地路由器)的MAC地址。和以前一样,如果内核不知道网关的MAC地址,则它必须广播ARP查询才能找到它。

此时,数据包已准备好通过以下任一方式进行传输:

  • 乙太网路
  • 无线上网
  • 蜂窝数据网

对于大多数家庭或小型企业的Internet连接,数据包将从您的计算机经过本地网络,然后再通过调制解调器(MOdulator / DEModulator)传递,该调制解调器将数字1和0转换为适合通过电话,电缆,或无线电话连接。在连接的另一端,是另一个调制解调器,该调制解调器将模拟信号转换回数字数据,以供下一个网络节点处理,在该网络节点中,将进一步分析from和to地址。

大多数大型企业和一些较新的住宅连接将具有光纤或直接以太网连接,在这种情况下,数据保持数字状态,并直接传递到下一个网络节点进行处理。

最终,数据包将到达管理本地子网的路由器。从那里,它将继续行进到自治系统(AS)边界路由器,其他AS,最后到达目标服务器。途中的每个路由器都将从IP标头中提取目标地址,并将其路由到适当的下一跳。对于每个经过的路由器,IP报头中的生存时间(TTL)字段将减一。如果TTL字段达到零或当前路由器的队列中没有空间(可能是由于网络拥塞),则该数据包将被丢弃。

该发送和接收在TCP连接流之后多次发生:

  • 客户端选择一个初始序列号(ISN),并将数据包的SYN位置1,以将其发送给服务器,以表明它正在设置ISN
  • 服务器收到SYN,并且心情愉快:

    • 服务器选择自己的初始序列号
    • 服务器设置SYN以指示它正在选择其ISN
    • 服务器将(客户端ISN +1)复制到其ACK字段,并添加ACK标志以指示它正在确认接收到第一个数据包
  • 客户端通过发送数据包确认连接:

    • 增加自己的序列号
    • 增加接收者确认号码
    • 设置ACK字段
  • 数据传输如下:

    • 当一侧发送N个数据字节时,它的SEQ增加该数量
    • 当另一方确认收到该数据包(或一串数据包)时,它会发送一个ACK数据包,其ACK值等于从另一方收到的最后一个序列
  • 要关闭连接:

    • 较近者发送FIN数据包
    • 另一端确认FIN数据包并发送自己的FIN
    • 靠近者用ACK确认对方的FIN

TLS握手

  • 客户端计算机将ClientHello使用其传输层安全性(TLS)版本,密码算法列表和可用压缩方法向服务器发送消息。
  • 服务器ServerHello以TLS版本,选定的密码,选定的压缩方法以及由CA(证书颁发机构)签署的服务器公共证书的形式向客户端回复消息。该证书包含一个公共密钥,客户端将使用该公共密钥来加密其余的握手,直到可以同意对称密钥为止。
  • 客户端根据其受信任的CA列表验证服务器数字证书。如果可以基于CA建立信任,则客户端将生成一串伪随机字节,并使用服务器的公共密钥对此进行加密。这些随机字节可用于确定对称密钥。
  • 服务器使用其私钥解密随机字节,并使用这些字节生成自己的对称主密钥副本。
  • 客户端将一条Finished消息发送到服务器,并使用对称密钥对到目前为止的传输哈希进行加密。
  • 服务器生成自己的哈希,然后解密客户端发送的哈希以验证其是否匹配。如果是这样,它将向Finished客户端发送自己的消息,该消息也使用对称密钥进行了加密。
  • 从现在开始,TLS会话将传输使用同意的对称密钥加密的应用程序(HTTP)数据。

HTTP协议

如果使用的网络浏览器是Google编写的,则不会发送HTTP请求以检索页面,而是发送请求以尝试与服务器协商从HTTP“升级”到SPDY协议。

如果客户端使用的是HTTP协议并且不支持SPDY,则它将以下格式的请求发送到服务器:

GET / HTTP / 1.1
主持人:google.com
连接方式:关闭
[其他标题]

其中,[other headers]是指一系列按HTTP规范格式化并以单行换行分隔的冒号分隔的键/值对。(这假定使用的Web浏览器没有违反HTTP规范的错误。这也假定Web浏览器正在使用HTTP/1.1,否则它可能不包含Host请求中的标头,并且请求中指定的版本GET将为HTTP/1.0HTTP/0.9

HTTP / 1.1为发送方定义了“关闭”连接选项,以指示响应完成后将关闭连接。例如,

连接方式:关闭

不支持持久连接的HTTP / 1.1应用程序必须在每条消息中都包含“关闭”连接选项。

发送请求和标头后,Web浏览器将单个空白换行符发送到服务器,指示请求的内容已完成。

服务器以表示请求状态的响应代码进行响应,并以以下形式的响应进行响应:

200 OK
[响应头]

紧跟一个换行符,然后发送的HTML内容的有效负载 www.google.com。然后,服务器可以关闭连接,或者如果客户端发送的标头请求连接,则保持连接打开以重新用于其他请求。

如果由网络浏览器发送的HTTP标头包含足够的信息,以便网络服务器确定自上次检索以来是否已对网络浏览器缓存的文件的版本进行了修改(即,如果网络浏览器包含ETag标头),则可能而是以以下形式的请求进行响应:

304未修改
[响应头]

而且没有有效载荷,Web浏览器会从其缓存中检索HTML。

解析HTML之后,Web浏览器(和服务器)GET / HTTP/1.1会对HTML页面引用的每个资源(图像,CSS,favicon.ico等)重复此过程,但请求 不是GET /$(URL relative to www.google.com) HTTP/1.1

如果HTML引用的资源与不在另一个域上 www.google.com,则Web浏览器将返回到解析另一个域所涉及的步骤,并针对该域执行到此为止的所有步骤。Host请求中的标头将设置为适当的服务器名称,而不是google.com

HTTP服务器请求句柄

HTTPD(HTTP守护程序)服务器是在服务器端处理请求/响应的服务器。最常见的HTTPD服务器是Linux的Apache或nginx和Windows的IIS。

  • HTTPD(HTTP守护程序)接收请求。
  • 服务器将请求分解为以下参数:

    • HTTP请求方法(无论是GETHEADPOSTPUT, PATCHDELETECONNECTOPTIONS,或TRACE)。如果直接在地址栏中输入网址,则为GET
    • 域,在这种情况下-google.com。
    • 请求的路径/页面,在这种情况下-/(因为未请求特定的路径/页面,所以/是默认路径)。
  • 服务器验证服务器上是否配置了与google.com对应的虚拟主机。
  • 服务器验证google.com可以接受GET请求。
  • 服务器验证是否允许客户端使用此方法(通过IP,身份验证等)。
  • 如果服务器安装了重写模块(例如Apache的mod_rewrite或IIS的URL Rewrite),它将尝试将请求与配置的规则之一进行匹配。如果找到匹配的规则,则服务器使用该规则重写请求。
  • 服务器将拉出与请求相对应的内容,在本例中,它将退回到索引文件,因为“ /”是主文件(某些情况下可以覆盖它,但这是最常见的方法)。
  • 服务器根据处理程序解析文件。如果Google在PHP上运行,则服务器使用PHP解释索引文件,并将输出流式传输到客户端。

浏览器的幕后

服务器向浏览器提供资源(HTML,CSS,JS,图像等)后,将执行以下过程:

  • 解析-HTML,CSS,JS
  • 渲染-构造DOM树→渲染树→渲染树布局→绘制渲染树

浏览器

浏览器的功能是通过从服务器请求并在浏览器窗口中显示它来显示您选择的Web资源。该资源通常是HTML文档,但也可以是PDF,图像或某些其他类型的内容。用户使用URI(统一资源标识符)指定资源的位置。

浏览器解释和显示HTML文件的方式在HTML和CSS规范中指定。这些规范由W3C(万维网联盟)组织维护,该组织是Web的标准组织。

浏览器用户界面有很多共同点。常见的用户界面元素包括:

  • 用于插入URI的地址栏
  • 后退和前进按钮
  • 书签选项
  • 刷新和停止按钮以刷新或停止当前文档的加载
  • 主页按钮,可带您进入主页

浏览器高级结构

浏览器的组件为:

  • 用户界面:用户界面包括地址栏,后退/前进按钮,书签菜单等。浏览器的每个部分都会显示,但您看到所请求页面的窗口除外。
  • 浏览器引擎:浏览器引擎在UI和呈现引擎之间封送动作。
  • 渲染引擎:渲染引擎负责显示请求的内容。例如,如果请求的内容是HTML,则呈现引擎解析HTML和CSS,然后在屏幕上显示解析的内容。
  • 网络:网络使用平台独立界面后面的不同平台的不同实现来处理诸如HTTP请求之类的网络调用。
  • UI后端: UI后端用于绘制基本小部件,例如组合框和窗口。该后端公开了不是平台特定的通用接口。它的下面使用操作系统用户界面方法。
  • JavaScript引擎: JavaScript引擎用于解析和执行JavaScript代码。
  • 数据存储:数据存储是一个持久层。浏览器可能需要在本地保存各种数据,例如cookie。浏览器还支持存储机制,例如localStorage,IndexedDB,WebSQL和FileSystem。

HTML解析

呈现引擎开始从网络层获取请求的文档的内容。通常以8kB的块完成。

HTML解析器的主要工作是将HTML标记解析为解析树。

输出树(“分析树”)是DOM元素和属性节点的树。DOM是文档对象模型的缩写。它是HTML文档的对象表示形式,是HTML元素与JavaScript之类的外界接口。树的根是“文档”对象。在通过脚本进行任何操作之前,DOM与标记几乎具有一对一的关系。

解析算法

无法使用常规的自上而下或自下而上的解析器来解析HTML。

原因如下:

  • 语言的宽容性质。
  • 浏览器具有传统的容错功能,可以支持众所周知的无效HTML情况。
  • 解析过程是可重入的。对于其他语言,源在解析期间不会更改,但是在HTML中,动态代码(例如包含document.write()调用的脚本元素)会添加额外的标记,因此解析过程实际上会修改输入。

浏览器无法使用常规的解析技术,因此无法使用自定义解析器来解析HTML。HTML5规范详细描述了解析算法。

该算法包括两个阶段:令牌化和树构建。

解析完成时的操作

浏览器开始获取链接到页面的外部资源(CSS,图像,JavaScript文件等)。

在此阶段,浏览器将文档标记为交互式文档,并开始解析处于“延迟”模式的脚本:应在解析文档后执行的脚本。文档状态设置为“完成”,并触发“加载”事件。

请注意,HTML页面上绝不会出现“无效语法”错误。浏览器会修复所有无效内容,然后继续。

CSS解释

  • 使用“ CSS词汇和语法语法”解析CSS文件,