这是一个很经典的面试题,主要是考察程序员是否对网络请求的整个步骤有一个比较详细的了解,整体上来讲是对OSI七层模型理解的考验。这个问题还有一个问法: 你在浏览器中输入百度的域名到你看到了百度的页面,中间经过了哪些步骤。
如图,我们到底是怎么能看到这个百度的页面的呢?
请求的封包是从应用层一直到物理层(从上往下)。其中,应用层、会话层、表示层合并为了应用层,物理层和数据链路层合并为了物理层,所以图上只画了四层结构。 相反的,请求的拆包是从物理层一直拆包验证到应用层,每个层都有自己对应的协议,如果请求的内存不符合协议规范,那么服务端会拒绝请求。
我们使用浏览器请求,那么请求使用的是Http协议,从应用层发起,浏览器会帮我们封装http的相关信息,进入开发者模式就可以查看到相关的http请求信息,当浏览器将http的请求包封装好之后,那么它会将包发给传输层。
传输层的协议比较出名的有tcp和udp,浏览器目前默认使用的是tcp协议,那么在传输层需要做到的就是封装好tcp的报文,tcp的报文包含了两台机器需要交互的端口号,例如http一般就是访问目标机器的80端口,当然还有tcp的其他包括序号确认,窗口确认等等信息,我们在讲tcp的时候再详细讲解,现在先看一个标准的tcp的报文格式:
协议对初学者来讲过于抽象,不是很好理解,其实它跟开发的时候设计的接口差不多,双方都以一个约定好的数据格式来传输数据,只不过小范围的业务之间的约定叫接口,这种所有互联网的机器都遵守的接口约定就叫做协议,你完全可以这么理解。
网络层相比于传输层来讲用到的协议就比较固定,主要是使用了IP协议,IP协议报文自然包含了自己的IP和目标地址的IP,报文格式如下: 需要注意的是,浏览器输入的是域名,IP层封装的时候是不知道域名的ip地址的,那么此时会请求DNS服务,默认先请求本机配置的DNS(即你自己配置的hosts文件),如果没有才会向网络DNS服务发起请求,直到获取到了域名解析的IP地址,将这个IP地址封装到IP协议数据之中后网络层的数据就封装完毕了。
物理层是最底层的封装了,大家都知道每个计算机的IP是会变化的,但是它的Mac地址是计算机的硬件出厂就固定的,相当于这台计算机的身份证信息,而IP相当于这台计算机的住址信息。 网络寻址的道理与送快递的逻辑基本一致,举个送快递的例子相信会更好理解。快递员要把快递送达,那么首先要先根据你的配送地址找到你的小区,但是你住的小区可能有很多住户,快递员不确定你是哪一户的,所以快递员还需要给你打电话确认你的手机号和姓名等信息(即身份信息),最后才能把快递交给你。 而网络传输也是这样,IP地址就相当于你的小区住址,而Mac地址就相当于你的手机号或者身份证号码(在小区是唯一的)。当网络请求到达目的计算机所在的内网时,这个内网的局域网中所有的机器就构成了一个“小区”,“快递员”还需要在这个小区内找到它要真正请求的计算机,这时候就需要封装这个计算机的Mac地址(身份证信息)才能准确的将请求交付给目的计算机。
那么假如发起请求的计算机在封装Mac层的没有目的机器的Mac地址怎么办,这个时候它会目标局域网发送一个arp请求,当这个请求到达目标局域网的路由器之后,路由器会在内网发送一个arp广播,这个广播的大概的作用就是相当于询问 “你们谁是ip为xx.xx.xx.xx的机器,我需要你的Mac地址”。然后收到广播的机器会做一个验证,符合这个ip条件就会把自己的Mac地址响应出去,这样请求机器就获取到了Mac地址,可以正常的封装Mac层的数据了。
请求机器将包封装完成之后,大概是如下的样子: 这个包在网络中传输时,路由器会将Mac数据和网络层得到ip数据解析出来,然后根据本地的路由表来选择一条最合适的网络通道,将请求的数据包一级一级的发送到目的网络中去,最后目标机器就可以获取到这个请求的包了。 目的机器获取到网络数据包之后,同样从包头开始解析,如上面的OSI七层的图一样,从Mac开始拆包验证,然后是IP验证,TCP协议的相关验证,最后才解析Http数据,拿到数据后目的机器根据你的请求数据返回给你对应的文本即可,返回的流程与请求的流程基本是一致的。
你从输入了www.baidu.com到看到百度页面经过了那些步骤,现在可以自己整理出一份比较完整的回答了吗?
