本文转载于公众号: 「程序媛小飞龙」,其博客地址位于我的友情链接页面。

引言

说来挺巧,今天我正在上「计算机网络」这门课的时候,刚好翻到了这篇文章,我个人比较喜欢这种使用不官方语言来描述的文章,通俗易懂,于是我经过作者的同意,转载了此文章。

上图的书是不是很亲切,刚好我上课的教材就是这本书,就像原作者所说的「这哥们看完得花半条命」。

几乎每个学习过计算机网络的人,都是从老师敲黑板,划重点的 OSI 七层模型 讲起,有没有真的理解透彻不要紧,记下来要考的!!!然而作为一个非硬件方向的软工妹纸,最怕面试官往这个里面深问细问,哈哈哈哈不知道大家有没有这种感觉。

为什么网络要分层?

这其实很好理解,隋朝开始就有吏部、户部、礼部、兵部、刑部、工部了,一个庞大的组织想要管理有序,必须要拆分出来,各有各的职责,出了事情直接定位,每一层可以制定自己的标准来解决好自己层面上的事情。

再比如一个项目分 dao 数据库层缓存层service 层controller接入层一样,每一层专注自己的部分,关于优势,把高内聚、低耦合、可维护性强这些词甩在网络分层上面也是适用的。

从专业角度看,程序设计要求、复杂的程序都需要分层。

OSI 模型(Open System Interconnection Reference Model),只是一种参考概念模型,并没有提供一个可以实现的方法,现在的因特网采用的是 TCP/IP 模型(五层)、TCP/IP 网络通信协议(四层)。

了解网络发展史会发现 OSI 模型出现的时间比 TCP/IP 晚,是在 TCP/IP 模型基础上面提出的,那时候 TCP/IP 协议应用已经成型了,各大运营商们不想再换。再加上 OSI 模型有些设计冗余,因此因特网最终选择了草根选手 TCP/IP,但是 OSI 在理论研究上面具有很大参考价值,所以各大教材都会提到 OSI.

有这五层模型进行分工合作,就可以用 TCP/IP 协议将计算机连起来通信啦。

物理层

声音传信靠声波,鸽子传信靠电磁波,电流传信靠电波。物理层需要解决利用传输介质传输比特流的问题。

两台电脑最简单的通信方式是一根双绞线,两个水晶头,交叉接法,连接两个电脑的网卡,配置一下 IP 地址、子网掩码、默认网关即可成为一个网络,这两台电脑就组成了一个最小的局域网,可以联机打拳皇了。第三个人想加进来,就可以加一个有多个口的集线器(hub)设备。一个网吧人想加入进来,可以加上交换机,交换机互联形成网络拓扑。一个城市的人都想加进来,就需要移动联通电信到处铺电缆光纤,建立基站。

数据链路层

以太网协议

物理层中,已经帮你把电信号转化成数字信号 010101001 形式,但是两台机器要交谈总不可能一个字节一个字节的使用你 01 交流,数据链路层要负责把这些无穷尽的 010011001 封装成一个个 来进行传输,这时以太网协议就诞生了, 也叫做 以太网帧,以太网协议规定成帧的各项规则,例如多少字节成一个帧等。以太网协议如下:

以太网

三个人一起互联打格斗游戏,是有严格的角色和顺序的,随便一个人发出信号,发给谁,谁接收,先接收哪个地方信号,发错了怎么办?这些都是数据链路层需要解决的问题。

MAC 地址

数据链路层也叫做 MAC 层,Medium Access Control 即媒体访问控制,专业词叫做「多路访问控制」。

数据发给谁接收,最早是只有集线器没有交换机的,三台电脑每台电脑发送信号都是通过广播的方式,广播出去哪一台电脑需要处理呢,每台电脑都需要一个标识能够在数据链路层表示自己,MAC 地址由此诞生,对应的物理设备是网卡接口,每块网卡的MAC 地址都是全球唯一的,生产时就固定了。但是网络通信中,却不用 MAC 地址进行通信,而是 IP 地址,读者可以自行思考一下原因。

有了身份了,以太网帧里面源 MAC 和目标 MAC 都有了,就能找到相应目标机器,数据在链路上广播,目标 MAC 的网卡就能判定这个是给自己的,将其收进来打开,拿掉 MAC,发现 IP 包的地址也是自己的,再拿掉 IP 层根据 TCP 层端口找到相应进程,返回也是一样的,源 MAC 就变成了目标 MAC。

APR 协议

有个问题就是,当机器们互相认识的时候,可以把目标机器的地址放进包里,如果有 n 台机器呢,一个网吧的人一起玩格斗,总不可能一个一个去问你的 MAC 地址是啥,于是就有了 APR 协议。

在局域网里面,如果知道了 IP 地址不清楚 MAC 地址,那么就广播吧,发送一个广播包,谁是这个 IP,谁来回答,回答的包里面会带上自己的 MAC 信息。为了防止每次都 APR 广播,机器本地会进行 APR 缓存,交换机就是具有 MAC 地址学习能力的设备,学习完之后就能精准找到主机,不需要广播。

网络层

上面其实已经提到过一些 IP 地址,计算机网络世界里面,都是通过 IP 地址来进行定位的,怎么配置自己的 IP 地址呢,其实可以使用 ipconfig,也可以 ip addr,将网卡 up 一下就可以,电脑小白都可以打开自己的电脑网络配置中心更改就行。

现实中我们的网络是由一个个局域网组成的复杂网络拓扑,每个局域网处于同一个网段,MAC 地址相当于这个人的 DNA,能精准到一个人,但是却是没有定位寻址功能的,MAC 地址没有为寻址功能设计编号,出厂后网卡被哪里使用不知道,中国都可以进口美国产的网卡,但是 IP 地址是有设计寻址功能的,每个地区的 IP,就像物流地址一样,能一层层定位到一个人的地址,黑客找人很多就是根据 IP 地址的。

DHCP(Dynamic HostConfiguration Protocol) 动态主机配置协议

如果局域网内只有几台主机,自己配置一下 IP 地址玩玩也是可以的,但是如果一个学校的电脑都需要网管来一个一个配置的话,那就不好玩了,所以我们需要一个可以自动配置 IP 的协议,即 DHCP

每台主机要加入一个网络的时候,肯定是什么也不知道,只知道自己的 MAC 地址,因此这个时候还是靠广播,使用 IP 地址0.0.0.0 发送一个广播包,发给目的地址 255.255.255.255,封装在 UDP 里面,UDP 封装在 BOOTP 里面(DHCP 的前身),DHCP SERVER 收到带有 MAC 地址的包,在没有 IP 地址的情况下就知道是谁索要 IP 了。

因此就给其子网掩码、网关和 IP 信息,然后这台新来的机器就可以欢快的加入大家庭了。

网关(gateway)

说了这么多还都是在局域网内小打小闹,外面的世界那么精彩,如果想要出国玩玩第一件事就是解决护照,才能通过网关,前面不止一次说到网卡配置的时候需要配置网关。

假如你配置的 IP 是 192.168.1.100,旁边兄弟的是 192.168.10.100,然后我要访问他,来看看电脑是怎么理解的,以下是 Linux 的处理方式:

网关大家可以理解成工作在网络层的路由器,它有多个网卡分别连着不同的局域网,每个网卡的 IP 地址都和对应局域网在同一个网段,工作时就像机场,你拿着哪一国护照就往哪一国送,会将 MAC 头和 IP 头都取下来,然后判断内容看将包往哪里转发。路由里面又分为静态路由、动态路由、路由算法等复杂的逻辑。

DNS(DOMAIN NAME SYSTEM)域名系统

如果你有超强的记忆力的话,当然能以 12.34.45.56 这样的方式去访问百度,就跟纯敲电话号码去给一个人打电话一样,但大多数人都是直接翻看通讯录找名称来打电话吧,网络世界也是一样,需要域名来标示一个 IP,于是你就可以通过www.baidu.com 来访问百度了。域名就是网络世界里面的通讯录。

想象一下,全世界都靠这个通讯录找人,它一旦挂了那么地球村就 gg 了,因此 DNS 服务器一定得高可用、高并发、分布式,这么复杂,第一反应肯定是分层设计的嘛,思想都是相通的,于是就有了根 DNS 服务器,顶级域 DNS 服务器,权威 DNS 服务器,如下:

DNS

树状结构,访问就需要递归了,为了提高 IP 解析性能,就需要缓存了,很多运营商(移动电信联通)会就近部署 DNS 缓存服务器,DNS 解析流程如下:

DNS 解析

CDN(content delivery network)缓存

访问一个地址都要这么复杂,找这么多层,现实中多等一秒都难受,那么就要想办法尽量走缓存拿数据,全球有那么多数据中心,我们不远的地方都有数据中心,何不在这些数据中心里面部署一些机器来做缓存集群缓存部分数据呢?于是 CDN 的角色就出来了,这里不细讲其具体形态,无外乎又是分层、高可用设计。

传输层

TCP、UDP
像物流系统一样,接单之后选好了路径,就要运货了,交通情况那么复杂,运货过程中肯定会遇到拥堵、丢货、超时等一系列问题。传输层就是为了解决这些问题而存在的,主要分为 UDP 协议和 TCP 协议,他们之间最主要的区别就是 UDP 不可靠TCP 可靠

UDP 协议适用于对丢包不敏感的应用,不需要建立连接,速度快,以上说到的 APR、DHCP 都是基于 UDP 协议的,还有直播的流媒体协议,早期对实时性要求高的游戏、物联网和移动通信领域等等。

TCP 要保证可靠传输,就要考虑到保证顺序丢包处理维护连接流量控制拥塞控制等问题,因此就出现了复杂的三次握手、四次挥手,还要维护 TCP 状态机等。拥塞控制是通过拥塞窗口来解决的,顺序、丢包处理、流量控制对应滑动窗口。

端口(port)
试想一下数据跋山涉水的到达了你的电脑,然后呢咋办,你同时开了微信、qq、钉钉,别人给你发条消息你总要运送到对应的程序吧,这样才算最终到达。

这里不妨把每个应用都理解成一个程序,端口的需要就体现出来了,这个端口在你电脑是不会重复的,要不然数据过来就没法判断了,很多人在玩 tomcat 的时候,开两个 8080 端口都会遇到报错吧。

应用层

到了应用层,就会比较具体了,毕竟我们看得见,每个人都有不同的需求,比如 A 需要发邮件,B 需要下订单,C 需要下载文件,这层需要解决告诉对方,我要干什么的问题,根据干的事情不一样,又会催化出各种不同的协议来最好解决你的需求。

http、https 协议
http 是最早的协议,其中分为了 POSTDELETEPUTGET 等请求,对应向服务器增删改查数据,然后发展到http 2.0。通过压缩、分帧、二进制编码、多路复用等技术提升性能,然后发展到 https,通过改进加密技术来提高安全性。