首先,我们要知道url的具体含义,比如:http://va1lid.top/songList

  • http: 代表协议
  • va1id.top:表示服务器的地址,需要通过DNS获取到具体的IP地址
  • /songList: 表示请求的具体的资源或者是服务,是相对于在web服务器配置中配置路径的位置。

我们把url输入到地址栏之后:

HTTP

首先构造HTTP的消息,请求行 + 请求头 + 数据

  • 请求行: 请求方法(GET, POST etc.)、请求地址、协议/版本号(HTTP 1.1)
  • 请求头:user-Agent、cookie etc.
  • 消息体:payLoad

HTTP 的消息格式

DNS

域名是具有层级的,以 点分割,比如: va1id.toptop是一级地址,va1id是二级域名。

启动DNS服务将服务器的域名解析为IP地址:

  • 首先向根域名服务器请求,他返回让去顶级域名服务器去请求

    大概就是,我的域名是… ,我想知道我的IP—根域名服务器讲你应该去找top域名服务器

  • 然后向顶级域名服务器请求,他返回让去权威域名服务器请求

  • 然后在权威域名服务器中找到IP地址返回

以上是应用层,等构造好HTTP数据之后,接下来会交给操作系统经过一个协议栈:

传输层(TCP: 端口) – 网络层(IP: IP地址) – 数据链路层(ARP: 物理地址)

接下来依次讲一下上面的协议栈:

传输层: TCP

TCP,是一种面向连接的,保证可靠交付的传输协议,它主要是保证交付给响应的应用,使用端口进行区分。

  • 源端口:标记来的应用
  • 目的端口:标记到达的应用
  • 序列号、确认号:用于累计确认
  • 发送窗口、接收窗口:用于拥塞和流量控制

在传送TCP包之前,首先要通过三次握手建立TCP的连接

  • client 发送SYN=1的数据包给server,client变为SYN_SENT状态
  • server收到之后,发送SYN = 1ACK = 1 给client,server变为SYN_RCVD状态,这里server确定了: client发送正常,server接收正常
  • client收到之后,发送ACK=1给server,client变为establish状态,client确定:client发送、接收正常,server接收、发送正常
  • server收到之后,进入establish状态,确定了server发送、接收正常,client发送、接收正常

进行TCP包构造:在这一层会加一个TCP的头,HTTP报文作为TCP的数据部分。

网络层:IP

在有了TCP保证传输到正确的应用之后,还需要传输给正确的服务器,就需要通过IP协议。

  • 源IP:
  • 目的IP:

这个需要路由器、路由表实现。

构造IP数据报:IP头部 + TCP包

数据链路层:点对点传输, ARP协议

  • 发送方的MAC地址:

  • 接收方的MAC地址:

构造MAC帧:MAC头部 + IP数据报

现在就有一个问题,MAC的发送方和接收方如何确认,

  • 发送方是当前的设备的MAC地址
  • 而接收方是根据IP数据报中的目的IP找到下一跳的IP地址
  • 找到下一跳的地址之后,并不是直接修改IP的目的IP,而是通过ARP协议找到下一跳的IP地址的MAC地址,再进行发送

ARP协议:

  • 首先向ARP的高速缓存中,查询是否存在目的IP对应的MAC地址,如果存在直接返回响应的MAC地址
  • 当前设备向局域网内广播,我的IP是 XXXX,我的MAC地址是XXXX,我要找IP地址是ABC的MAC地址
  • 局域网内的其他设备收到之后,如果不是ABC的IP,会讲源IP和MAC加入到高速缓存,ABC的IP对应的设备,会返回自己的MAC地址,然后更新自己的高速缓存
  • 当前设备收到后,更新高速缓存,然后将构造MAC帧的头部

还要经过网关的封装之后,可以进行发送,在发送的过程中会遇到两个重要的设备。

交换机

交换机是一种工作在数据链路层的设备,不具有网卡和MAC地址,只具有端口,相当于网桥。里面有MAC地址表对应于端口号,通过这张表进行转发,如果表中没有MAC地址的话,就广播一条消息,只有相对的MAC地址设备可以接收,其他的设备会忽略,同时MAC表中会加入这条记录

路由器

​ 路由器是工作在网络层的设备,在路由器中会对MAC头部拆除,通过IP数据报的的目的IP地址在路由表中查找下一跳的位置,通过ARP找到相应的MAC地址,再对MAC层的头部进行封装。

在这个过程中源IP和目的IP是一直保持不变的,发生变化的MAC地址。

后来

在通过以上的协议到达服务器的地址之后,通过不断的拆包,向上传递给相应的应用。

如果请求是一个资源的话,则直接会通过HTTP将资源返回。

如果请求的是一个服务的话,则需要通过web服务器,对服务进行响应,MVC那一套。

再通过上面的协议对资源进行返回。