互联网世界中,网络协议的重要性不言而喻。很多人都知道,网络协议中的五层模型或者七层模型,这些在操作系统中,那都是“必考题”。上学的时候,无论是死记硬背,还是各种小抄,总得把下面这个图记下来。踏入工作,走进 web 开发“不归路”,发现还是不能落下它。
协议三要素
- 语法,就是一段内容要符合一定的规则和格式。例如,括号要成对,结束要使用分号等。
- 语义,就是这段内容要代表某种意义。例如,数字相减是有意义的,而数字减去文本一般来说就没有意义。
- 顺序,就是规定先干什么,后干什么。就像我们常做的,先加某个数值,再减去某个数值等。
HTTP 协议:
HTTP/1.1 200 OK
Date: Thu, 25 Oct 2018 01:56:12 GMT
Content-Type:
Content-Language:
<!DOCTYPE html>
<html>
<head>
<base href="http://blog.muzixizao.com/" />
<Meta charset="utf-8"/> <title>木子与西早的博客屋 </title>
我们来看看上面的 HTTP 协议是否符合协议的三要素。
首先,符合语法,也就是说,只有按照上面那个格式来,浏览器才能解析。例如,上面是状态,然后是首部,最后是内容。
其次,符合语义,就是要按照约定的意思来。例如,状态 200,表示网页成功返回。如果不成功,就是常见的 404。
最后,符合顺序,点击浏览器,就是发送一个 HTTP 请求,然后才有上面那串返回的东西。
浏览器显然按照协议商定好的做了,才能将网页呈现在你面前。
常用的网络协议
我们面试的时候经常会被问到这样一个问题:
我们就用打开博客的过程,看看互联网世界运行过程中,都使用了哪些网络协议。
当在浏览器里输入 “http://blog.muzixizao.com”,这是一个 URL,而浏览器知道它的名字是 blog.muzixizao.com,但是不知道具体的地点,所以浏览器不知道如何访问。
于是,它打开地址簿去查找。在这个过程中,我们一般使用地址簿协议-DNS,还可以使用另一种更加精准的地址簿查找协议-HTTPDNS。
无论使用哪一种方法查找,最终都可以得到这个地址:47.106.81.116。这个是 IP 地址,可以把它当做是互联网世界的“门牌号”。
知道了目标地址,浏览器就开始打包它的请求。对于普通的 HTTP 请求,一般会使用 HTTP 协议,但是如果对于购物的请求,往往会进行加密传输,因而会使用 HTTPS 协议。无论是什么协议,里面都会写明“我要看哪篇博文”。
DNS、HTTP、HTTPS 所在的层我们成为应用层。经过应用层封装后,浏览器会将应用层的包交给下一层去完成,通过 socket 编程来实现。下一层是传输层。传输层有两种协议,一种是无连接的协议 UDP,一种是面向连接的协议 TCP。而所谓的面向连接就是,TCP 会保证这个包能够到达目的地,如果不能到达,就会重新发送,直至到达。
TCP 协议里面会有两个端口。一个是浏览器监听的端口,一个是博客服务器监听的端口。操作系统往往通过端口来判断,它得到的包应该给哪个 进程。
传输层封装完毕后,浏览器会将包交给操作系统的网络层。网络层的协议是 IP 协议。在 IP 协议里面会有源 IP 地址和目标 IP 地址,也就是浏览器所在机器的 IP 地址和博客网站所在服务器的 IP 地址。
操作系统既然知道了目标 IP 地址,下一步就是根据这个 IP 找到目标机器。它首先会判断,这个目标 IP 是本地人还是外地人。从 IP 很明显就能看出来,博客服务器不在本地。
操作系统知道了,要到目标机器,就要要离开本地去远方。那如何去远方呢?这个时候就可以拿出国旅游作类比。我们要去国外,就要经过海关。同样的,操作系统要去远方,也要经过网关。而操作系统启动的时候,就会被 DHCP 协议配置 IP 地址,以及默认的网关 IP 地址:192.168.1.1。
操作系统如何将 IP 地址发给网关呢?在本地通信基本靠吼,于是操作系统大吼一声,谁是 192.168.1.1 ?网关会回答它,我就是,我的本地地址在村东头。这个本地地址就是 MAC 地址,而大吼的那一声就是 ARP 协议。
操作系统拿到了 MAC 地址,就将 IP 包交给了下一层:MAC 层。网卡再将这个包含 MAC 地址的包发出去。由于这个包里面有网关的 MAC 地址,因而它能够到达网关。
网关收到包之后,会根据自己的知识,判断下一步应该怎么走。网关往往是一个路由器,到某个 IP 地址应该怎么走,这个叫做路由表。
路由器有点像玄奘西行路过的一个个国家的城关。每个城关连接着两个国家,每个国家相当于一个局域网,在每个国家内部,都可以使用本地的地址 MAC 进行通信。
一旦跨越城关,就需要拿出 IP 头来,里面写着贫僧来自东土大唐(源 IP 地址),想去西天(目标 IP 地址)拜佛求经。路过此地,借宿一晚,明日启行。请问接下来该怎么走?
城关往往是知道这些“知识”的,因为城关和临近的城关也会经常沟通。到哪里应该怎么走,这种沟通的协议称为路由协议,常用的有 OSPF 和 BGP。
城关与城关之间是一个国家,当网络包知道了下一步去哪个城关,还是要使用国家内部的 MAC 地址,通过下一个城关的 MAC 地址,找到下一个城关,然后再问下一步的路怎么走,一直到走出最后一个城关。
最后一个城关知道这个网络包要去的地方,于是,就对着这个国家吼一声(ARP协议),谁是目标 IP ?目标服务器就会回复一个 MAC 地址。网络包过关后,通过这个 MAC 地址就能找到目标服务器。
目标服务器发现 MAC 地址对上了,取下 MAC 头来,然后发送给操作系统的网络层。网络层发现 IP 也对上了,就取下 IP 头。 IP 头里会写上一层封装的是 TCP 协议,然后将其交给传输层,即 TCP 层。
在这一层里,对于收到的每个包,都会有一个回复的包说明收到了。这个回复的包不是这次请求的结果,而仅仅是 TCP 层的一个收到回复。这个回复会沿着刚才来的方向走回去,报个平安。
如果过一段时间,发送端的 TCP 层没有收到平安回复,就会重新发送这个包,重复上面的过程,直到收到平安到达的回复为止。这个重试不是浏览器重新进行请求,对于浏览器而言,只发送一次请求,而 TCP 层在没有收到平安回复时,不断闷头重试。除非 TCP 层出了问题,比如连接断了,才需要浏览器的应用层重新发送请求。
当网络包平安到达 TCP 层后,TCP 头中有目标端口号,通过这个端口号,可以找到博客网站的进程正在监听这个端口号,假设是 Nginx,于是就将这个包发给 Nginx,进行相关业务处理。处理完成后,将相关数据打包,然后回复给浏览器,显示出博文页。
下图就是整个HTTP 请求中可能用到的协议。后续会通过从底层到上层的顺序来一一分享。