聊聊网络协议——基础篇
0. 前言
对于架构师而言,他们“上能九天揽月,下能五洋捉鳖”。之所以给人以无所不能的印象,主要在丰富的知识储备。网络协议作为架构师基础知识体系也是必须要掌握的。本文介绍一些架构师需要了解和掌握的基础网络协议概念。
1. 概念
计算机网络
在介绍之前我们先聊一下什么是计算机网络,顾名思义,网络就是将多台计算机相互连接其他,使他们能够互相通讯。
(图1)
图1是最简单的计算机网络,我们将两台电脑通过一根线缆连接就做成了一个计算机网络,这两台电脑就可以相互通信。
我们进一步解析这张图。
硬件设备
要想使两台计算机相互连接,首先需要连接介质,这里是一根线缆(也可以通过无线信号)——网线,计算机上需要有支持连接线缆的设备——网卡。如果我们是多台机器互联,我们需要交换机和路由器等设备。我们统称这些问网络硬件设备。
软件支持(网络协议)
了解计算机系统的人都知道,只有硬件没有软件,计算机就是一堆废铁。对于网络也一样,网络设备负责将计算机在物理层次连接起来,网络协议负责计算机之间的交流和通信。
计算机终端间要想正确的传递信息和数据,必须在数据传送的顺序、数据的格式和数据内容方面有相应的约定或规则,这些我们称之为网络协议。
网络协议就像人类之间的语言,只有讲同一种语言的人才能相互交流并明白对方的意思。对于计算机网络而言只有使用同一种网络协议的计算机之间才能通信。使用不同协议的计算机语言即使能收到对方信息,但是因为不能明白对方意思,相互也无法交流和通信。
严格意义上说,网络协议并不是真正的软件,他只是软件实现的规范和方面,
2. 分层模型
从软件架构上看,复杂的软件都需要分层。每层定义一些职责,层与层之间有依赖关系,层与层之间各司其职,组合起来共同实现同一个软件目标。分层可以显著降低软件整体复杂性和耦合性,使每一层实现起来更加容易。网络这个复杂架构也使用分层的方式,常见的网络协议模型有OSI七层协议和TCP/IP四层协议
2.1 OSI七层参考模型
OSI的七层参考模型。传统的开放式系统互连参考模型,是一种通信协议的7层抽象的参考模型。 七层模型只是一个分类参考,只定义了每一层大致的职责。并没有给成具体实现。协议实现方可以参考七层分类原则实现自己的协议。
2.2 TCP/IP四层模型
TCP/IP是指能够在多个不同网络间实现信息传输的协议簇。协议簇说明由一组协议组成,其中最耳熟能详的两个协议是TCP协议和IP协议所以整个协议簇由有这两个协议命名的。
从某种意义上说TCP/IP协议簇是对OSI七层参考模型具体的解释和协议维度实现,OSI只是定义了每一层职责,TCP/IP则定义了完成这些职责的具体协议。除了TCP协议和IP协议外常见的还有:Telnet、HTTP、HTTPS、SMTP、FTP、NTP、DHCP、ICMP、ARP、PPTP等。TCP/IP对OSI七层模型做了简化,简化为四层。
3. 各层依赖
从软件架构上说,上层架构依赖底层架构。网路协议也类似,我们以7层HTTP协议为例:
如图所示,HTTP协议每一次请求都需要底层协议参与完成。所以对于网络而言,上层协议依赖底层协议实现,只存在有下层协议参与没有上层协议参与的情况,不存在有上层协议参与而没有下层协议参与的情况。
4. 封装
网络中传输的数据是一个一个的数据包,数据包需要想被各层协议处理除了本身传输数据之外,还要带上各个协议的特征值,为协议处理提供线索。为传输数据加上协议特征值的行为就是封装。与封装对应的两个行为就是打包和解包过程。
(HTTP发消息数据包打包解包的图)
打包过程:
发送数据的时候随着数据的调用方向由上而下的将经过协议的数据包装于上层协议之外,最后呈现的结果是底层协议内容在外面,上层协议的内容在里面。这就是一个打包的过程。
解包过程:
接受数据的时候和发送数据时候经历的协议处理过程正好相反。底层协议识别自己协议包内容,将本层内容去除后将里面的内容继续向上传递。这就是一个解包的过程。
打包和解包构成了一条数据经过协议后完整操作流程。
分层、依赖和封装是网络协议中比较基础的概念。他们分别从结构、关系和行为等方面为我们描述了网络协议的各角度视图。
5. MAC地址和IP地址
5.1 MAC地址
MAC地址是一个网卡(网卡是处理网络传输数据的底层设备)的物理地址,MAC 地址号称全局唯一,不会有两个网卡有相同的 MAC 地址。MAC地址更像一个对网卡的标识,它的唯一性设计是为了组网的时候,不同的网卡放在一个网络里面的时候,可以不用担心冲突。从硬件角度,保证不同的网卡有不同的标识。
5.2 IP地址
大部分的网卡都分配一个 IP 地址,IP地址相当于网卡在网络世界的通讯地址。例如10.0.45.193 就是一个 IP 地址。这个地址被点分隔为四个部分,每个部分 8 个 bit,所以 IP 地址总共是 32 位。
IP地址氛围公有IP地址和私有IP地址,公有IP地址通常由某个组织统一分配,是独占资源,分配给你了就不能分配个别人。私有IP地址在我们内部局域网使用,由网络管理员自己分配和管理,不同的局域网间可以分配相同的私有IP。
5.3 MAC地址和IP地址的区别
MAC地址可以类比身份证号码,每一个身份证号码可以唯一标识一个人。IP地址就相当于身份证中的地址信息。当我们要找一个人只能通过地址查询,通过一个身份证号码是无法知道这个人现在身在何处的。
6. CIDR
CIDR是无类型域间选路的简称,他将 32 位的 IP 地址一分为二,前面是网络号,后面是主机号。
例如:10.0.45.193/24,这个 IP 地址中有一个斜杠,斜杠后面有个数字 24。这种地址表示形式,就是 CIDR。后面 24 的意思是,32 位中,前 24 位是网络号,后 8 位是主机号。网络号就是我们说的网段,同一个网络号就是在同一个网段,不同网路号就是不同网段。
伴随着 CIDR 存在的,一个是广播地址,10.0.45.255。如果发送这个地址,所有 10.0.45 网络里面的机器都可以收到。另一个是子网掩码,255.255.255.0。将子网掩码和 IP 地址进行 AND 计算。前面三个 255,转成二进制都是 1。1 和任何数值取 AND,都是原来数值,因而前三个数不变,为 10.100.122。后面一个 0,转换成二进制是 0,0 和任何数值取 AND,都是 0,因而最后一个数变为 0,合起来就是 10.0.45.0。这就是网络号。将子网掩码和 IP 地址按位计算 AND,就可得到网络号。
我们说过IP地址有定位的能力,网络号就相当于小区的地址,主机号就相当于具体门牌号。
7. 二层网络协议
数据链路层,MAC 的全称是 Medium Access Control。数据链路层负责在一个局域网内传输数据,局域网内机器都是同一网段。如果一条数据已将到了一个局域网内,就由二层网络协议负责数据的传输。
二层网络中的设备通过交换机相互连接,我们可以将交换机理解为多根网线的集线器,保证所有机器物理上连通。
二层网络主要解决三个问题:
数据包有谁发送的?又有谁接收?
大家都在发,会不会产生混乱?谁先发?谁后发?
包出现错误怎么办?
问题1和问题3通过二层数据包内容定义就可以解决:
二层网路数据包中有目标MAC地址和源MAC地址,可以解决问题1。数据包中有一个CRC校验位,用来解决问题3,如果数据和CRC校验内容不符,说明数据在传输过程中损坏,包不会被接收。
(二层数据包图)
问题2有三种解决方式:
信道划分:效率最高,但是信道过多占用资源。
轮流协议:类似于悲观锁,数据串行传输,先来的数据先传,后到的数据的需要等前面的数据传输完毕在传输,避免冲突。
随机接入协议:类似于乐观锁,数据到了就传输,有冲突稍后在重试。
我们可以想象在同等资源消耗下随机接入协议传输性能最好,以太网就是使用这个方式。
ARP协议
通常情况下我们通过IP地址请求某一台机器,但是只知道IP地址不知道机器的Mac地址无法完成二层网络协议的封装,也就无法发送数据。这时候我们需要ARP协议。
ARP在二层网段中发送广播信息,类似于大喊一声谁是IP地址为XXX的机器,你的网卡MAC地址是多少。收到消息的机器就会回答这条信息,这样发送方就知道了IP地址为XXX的机器的MAC地址是多少了。当然我们不会每次请求都广播一下ARP,发送方会将一次ARP内容缓存起来供下次使用。
8. 三层网络协议
当我们访问地址的网段和当前机器的网段不在统一网段,说明我们已经卖出了二层网络,进入了三层网络。三层网络协议主要处理局域网间访问,从一个局域网“跳”进另一个局域网。这个跳跃的过程是通过IP实现的。
在任何一台机器上,当要访问另一个 IP 地址的时候,都会先判断,这个目标 IP 地址,和当前机器的 IP 地址,是否在同一个网段。
如果是同一个网段,直接将源地址和目标地址放入 IP 头中,然后通过 ARP 获得 MAC 地址,将源 MAC 和目的 MAC 放入 MAC 头中,发出去就可以了
如果不是同一网段,这就需要发往默认网关。网关往往是一个路由器,是一个三层转发的设备,他将MAC头和IP头(三层数据包)都取下来,然后根据里面的内容,看看接下来把包往哪里转发的设备。
通过二层网络和三层网络两层网络,我们解决了将计算机连接起来目标,世界上任意两台计算机之间可以相互访问。
9. 四层网络协议
我们已经将计算机连接起来,但是我们实际需要连接的不是计算机,而是计算机中的软件。这就是四层网路主要解决的问题,连接两台计算机中的软件。
我们通过引入端口号来区分同一台计算机中的不同软件。发送发程序有一个端口号,接收方程序同样有一个端口号,消息通过端口号识别相互传输的计算机中的程序。
网络是一个复杂的环境,网路层IP并不保证数据一定传输到站。
四层网络协议对三层进行封装,提供了保证数据传输的能力:
TCP和UDP是四层两个重要的协议,他们都对IP协议进行封装,实现数据端到端传输能力。
以下是为两者区别:
TCP 是面向连接的
TCP提供可靠数据交付能力,数据无差错、不丢失、不重复、并且按序到达
TCP 是面向字节流的
TCP 是可以有拥塞控制的
UDP 是面向无连接的
UDP不保证不丢失,不保证按顺序到达
UDP 基于数据报的
UDP没有拥塞控制能力
两个协议最主要的区别TCP提供了可靠传输能力。实际使用中我们需要根据不同的场景选择合适的协议。例如,HTTP协议通常需要可靠传输,使用TCP协议作为实际传输保证。而类似于直播的场景,无需保证可靠传输,则可以使用UDP协议。
至此我们完成了端到端通讯的全部基础能力。使用这些基础协议,我们可以衍生出各类应用程序协议。
10. 七层网络协议
在1-4层协议的基础上,我们已经拥有了所有计算机通信的能力,任意两台机器中的程序可以通过网络相互传递消息。有了这个基础能力,我们可以结合现实场景演化出各式各样使用方式。七层应用层就是借助底层协议能力制定出适合各类场景的协议。常见的如HTTP、HTML和FTP。
其实协议并没有想象的中得那么神秘,说白了就是规定了传输的格式、内容,使用什么方式传输和各种异常场景等。
任何人都可以根据协议要求通过代码实现一套自己的应用程序。引用一篇旧文来说明如何开发自己的Web服务器:《一步一步实现Tomcat之一——实现一个简单的Web服务器》
11. 总结
本文开篇从宏观视角介绍了网络七层模型中各层的职责和主要构成的协议。让我们对网络是如何组成的和计算机是如何通过网络进行通信的有了一个初步的了解。
1至4层中涉及的具体协议都已经由操作系统实现了,应用层各类网络应用程序都是构建在四层TCP或UDP协议之上的,这也是我们日常工作的场景。各种编程语言都对操作系统协议实现进行了抽象和封装,如Java的Socket编程接口。
文章结尾引入了一个简单Web服务器示例,下篇文章我们会以这个示例展开,在实践场景下,进一步介绍如何实现一个高性能的Web服务器?如何使用Java中网络编程中阻塞IO模型和NIO模型编程?
版权声明: 本文为 InfoQ 作者【Jerry Tse】的原创文章。
原文链接:【http://xie.infoq.cn/article/49406b19eaedcfe577e49d969】。文章转载请联系作者。
评论