浅谈网络协议(一) 为什么要学网络协议

最近在学习网易研究院云技术部首席架构师刘超先生的趣谈网络协议,开一个系列记录一下。

本系列文章是在原作的基础上修正,并加以自己的见解进行二次编辑,在此特地说明

先看一段代码

public function hello()
{
    echo 'Hello World';
}

这是一段PHP的代码,当然即使你不是个PHPer,你也肯定能看懂这段代码。但是,你不一定知道,这也是一种协议,是人类和计算机沟通的协议,只有通过协议,计算机才知道我们想让它做什么。

协议三要素

当然,这种协议更接近人类语言,机器不能直接读懂,需要进行翻译,翻译的工作交给编译器,也就是compile。

编译

编译的过程比较复杂,具体不细说,但是可以看出,计算机语言作为程序控制一台计算工作的协议,具备了协议的三个要素:

  • 语法,就是一段内容要符合一定的规则和格式,例如括号要成对,结束要用分号。
  • 语义,就是一段内容要代表某种意义,例如数字减数字是有意义的,数字减文本一般来说就没有意义。
  • 顺序,就是按照某种顺序执行。

会了计算机语言,就能让一台计算机完成工作了。但是,想要让互联网世界的所有机器协同工作。就需要网络协议。只有通过网络协议,才能使一大片机器相互协作,共同完成一件事情。

打开浏览器,输入购物网站的地址,浏览器会给你一个多彩的页面。那么浏览器是如何做到这件事情的?之所以能够呈现多彩的页面,是因为它收到了一段来自 HTTP 协议的东西。拿百度举例,HTTP协议格式就如下面这样:

HTTP/1.1 200 OK
Date: Tue, 27 Mar 2018 18:00:00 GMT
Content-Type: text/html;charset=UTF-8
Content-Language:zh-ZN
--空行--
<!DOCTYPE html>
<html>
<head>
<base herf="https://www.baidu.com" />
<meta charset="utf-8" /><title>百度一下,你就知道</title>

看看上面的三要素。

首先,符合语法,只有按照上面那个格式来,浏览器才能识别。例如,上来是状态,然后是首部,然后是内容。

第二,符合语义,就是要按照约定的意思来。例如,状态200代表成功返回,如果不成功则返回404

第三,符合顺序,一点浏览器,就是发送出一个HTTP请求,然后才有上面一串返回的东西。

常用的网络协议

https://www.baidu.com ,这是一个URL,浏览器只知道名字是"www.baidu.com", 但是不知道具体的地点,所以不知道应该如何访问,于是它打开地址簿去查找。这个时候使用一般的地址簿协议DNS去查找,还可以使用另一种更加精准的地址簿查找协议HTTPDNS。

无论哪一种方法查找,最终都会得到这个地址: 183.232.231.173。这个是IP地址,是互联网世界的门牌号。知道了目标地址,浏览器就开始打包它的请求,往往会使用 HTTP 协议;但是对于购物等请求,往往需要进行加密传输,因而会使用 HTTPS 协议。无论是什么协议,里面都会写明"你要买什么,买多少",这些信息都是放在协议中
购买

DNS、HTTP、HTTPS所在的层我们称为应用层。经过应用层封装后,浏览器会将应用层的包交给下一层去完成,通过 socket 编程来实现。下一层是传输层。传输层有两种协议,一种是无连接的协议UDP,一种是面向连接的协议TCP。对于支付来讲,往往使用TCP协议。所谓面向连接就是,TCP会保证这个包能够达到目的地。如果不能达到,就会重新发送,直到到达。

TCP 协议里面会有两个端口,一个是浏览器监听的端口,这个是浏览器给予的。一个是服务器监听的端口,这个是根据上层协议给予的,如果是HTTP协议,就是80,如果是HTTPS,就是443,以此类推。操作系统往往通过端口来判断,它得到的包应该给哪个进程。在传输层中,端口的数据会被带上。

传输层封装完毕后,数据包继续交给操作系统的网络层。网络层的协议是 IP 协议。在 IP 协议里面会有源 IP 地址,即浏览器所在机器的 IP 地址和目标 IP 地址。

操作系统获取目标 IP 地址之后,就开始想如何根据IP找到目标机器。操作系统往往会判断,这个目标 IP 地址是内部地址,还是外部地址。如果是内部地址,从IP就能看出来,但是显然一般网站服务器地址不在本地,而在遥远的地方。

要去外部网络,需要经过网关。而操作系统启动的时候,就会被 DHCP 协议配置 IP 地址,以及默认的网关的 IP 地址 192.168.1.1。

操作系统如何将 IP 地址发给网关呢?在本地通信基本靠吼,于是操作系统大吼一声,谁是 192.168.1.1 啊?网关会回答它,我就是,我的本地地址在村东头。这个本地地址就是MAC地址,而大吼的那一声是ARP协议。

地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。地址解析协议是建立在网络中各个主机互相信任的基础上的,网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。ARP命令可用于查询本机ARP缓存中IP地址和MAC地址的对应关系、添加或删除静态对应关系等。

OSI模型把网络工作分为七层,IP地址在OSI模型的第三层,MAC地址在第二层,彼此不直接打交道。在通过以太网发送IP数据包时,需要先封装第三层(32位IP地址)、第二层(48位MAC地址)的报头,但由于发送时只知道目标IP地址,不知道其MAC地址,又不能跨第二、三层,所以需要使用地址解析协议。使用地址解析协议,可根据网络层IP数据包包头中的IP地址信息解析出目标硬件地址(MAC地址)信息,以保证通信的顺利进行。

于是操作系统将 IP 包交给了下一层,也就是MAC 层。网卡再将包发出去。由于这个包里面是有 MAC 地址的,因而它能够到达网关。

网关收到包之后,会根据自己的知识,判断下一步应该怎么走。网关往往是一个路由器,到某个 IP 地址应该怎么走,这个叫作路由表。

外部网络,即网关与网关之间是通过IP地址联系,而一个局域网内部,都可以使用本地的MAC地址进行通信。

网关往往是知道这些“知识”的,因为网关和临近的网关也会经常沟通。到哪里应该怎么走,这种沟通的协议称为路由协议,常用的有OSPF和BGP。

最后一个网关知道这个网络包要去的地方。于是,通过ARP找到目标服务器的MAC地址,通过这个 MAC 地址就能找到目标服务器。

目标服务器发现 MAC 地址对上了,取下 MAC 头来,发送给操作系统的网络层。发现 IP 也对上了,就取下 IP 头。IP 头里会写上一层封装的是 TCP 协议,然后将其交给传输层,即TCP 层。

在这一层里,对于收到的每个包,都会有一个回复的包说明收到了。这个回复的包绝非这次下单请求的结果,例如购物是否成功,扣了多少钱等,而仅仅是 TCP 层的一个说明,即收到之后的回复。当然这个回复,会沿着刚才来的方向走回去,表示已经收到数据包

如果过一段时间还是没到,发送端的 TCP 层会重新发送这个包,还是上面的过程,直到有一天收到平安到达的回复。这个重试绝非你的浏览器重新将下单这个动作重新请求一次。对于浏览器来讲,就发送了一次下单请求,TCP 层不断自己闷头重试。除非 TCP 这一层出了问题,例如连接断了,才轮到浏览器的应用层重新发送下单请求。

当网络包平安到达 TCP 层之后,TCP 头中有目标端口号,通过这个端口号,可以找到电商网站的进程正在监听这个端口号,假设一个 nginx,由nginx将这个请求通过socket转发给电商网站服务器。

电商网站的服务器的进程得到 HTTP 请求的内容,知道了要买东西,买多少。往往一个电商网站最初接待请求的这个 nginx 只是个接待员,负责统筹处理这个请求,而不是所有的事情都自己做。例如,这个接待员要告诉专门管理订单的进程,登记要买某个商品,买多少,要告诉管理库存的进程,库存要减少多少,要告诉支付的进程,应该付多少钱,等等。

如何告诉相关的进程呢?往往通过 RPC 调用,即远程过程调用的方式来实现。远程过程调用就是当告诉管理订单进程的时候,接待员不用关心中间的网络互连问题,会由 RPC 框架统一处理。RPC 框架有很多种,有基于 HTTP 协议放在 HTTP 的报文里面的,有直接封装在 TCP 报文里面的。

当接待员发现相应的部门都处理完毕,就回复一个 HTTPS 的包,告知下单成功。这个 HTTPS 的包,会像来的时候一样,经过千难万险到达你的个人电脑,最终进入浏览器,显示支付成功。

小结 一个简简单单的下单过程,中间牵扯到这么多的协议。而管理一大片机器,更是一件特别有技术含量的事情。除此之外,像最近比较火的云计算、容器、微服务等技术,也都需要借助各种协议,来达成大规模机器之间的合作。

这里列一下之后要讲的网络协议,之后会按照从底层到上层的循序来更新讲解。

问题:当网络包到达一个城市城关的时候,可以直接通过路由得到达下一个城关的IP地址,直接通过IP地址找就可以了,为什么还要通过本地的MAC地址呢?

ip是网络层使用的 mac是链路层使用的 ip包最终还是要通过物理链接和mac地址进行交互的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章