网络发展史
独立模式
在最开始计算机被发明出来,但网络还未普及的情况下,每个计算机之间都是相互独立的:
假设现在有一份数据需要处理,然后这份数据的处理又分给三个人分别处理。假设小松处理进行第一部分的处理,当小松处理完后,就需要将数据交给小竹。但是小竹处理数据的计算机是另一台,此时又没有网络,所以小松就需要通过硬件的方式,将数据拷贝到一个硬件,例如软盘中:
通过这类硬件,将数据从一台计算机拷贝到另一台计算机。这种数据交换的方式无疑是非常麻烦耗时的。
网络互联
网络互连:将多台计算机连接在一起,完成数据共享。数据共享本质是 网络数据传输 ,即计算机之间通过网络来传输数据,也称为 网络通信 。
局域网LAN
局域网,即 Local Area Network,简称LAN。
Local 即标识了局域网是本地,局部组建的一种私有网络
广域网WAN
如果有北、中、南等分公司,甚至海外分公司,把这些分公司以专线方式连接起来,即称为 “ 广域网 ” 。如果属于全球化的公共型广域网,则称为互联网(又称公网,外网),属于广域网的一个子集。有时在不严格的环境下说的广域网,其实是指互联网。所谓 " 局域网 " 和 " 广域网 " 只是一个相对的概念。比如,我们有 " 天朝特色 " 的广域网,也可以看做一个比较大的局域网。局域网,我们可以看成在同一个路由器内运行的主机集合。这些主机在这个路由器中可以不通过路由器直接交换数据。而广域网,则可以看成是多个不同的局域网集合,需要通过路由器来实现数据交换。
总的来讲,局域网和广域网都可以看做是一个相关概念,广域网可以看成一个比较大的局域网。
网络通信基础
IP地址
特殊 IP127.* 的 IP 地址用于本机环回 (loop back) 测试,通常是 127.0.0.1本机环回主要用于本机到本机的网络通信(系统内部为了性能,不会走网络的方式传输),对于开发网络通信的程序(即网络编程)而言,常见的开发方式都是本机到本机的网络通信
IPv4的ip地址是用4字节的无符号整数表示的,一共可以表示出2^32,即42亿左右的ip地址。但是根据2022年的数据,当今世界的网民已经有接近50亿人了,假设人手一台网络设备,ip地址就已经不够用了,更不用说当今推行的物联网时代,越来越多的物品可以联网,这也就导致继续采用IPv4协议的话,ip地址已经严重不足了。当然,有人可能会问,既然ip地址已经严重不足了,那为什么当前的网络使用却没有什么问题呢?这其实就涉及到IPv4的公网ip、私网ip等问题。在这里,大家只用知道,IPv4所能提供的ip地址已经无法满足未来的网络发展需求即可。
IPv6的ip地址是采用16位的无符号整数来表示的,根据指数爆炸的概念我们可以知道,IPv6所能表示的ip地址数量就远远超过IPv4。但是,当今时代主要使用的ip协议是IPv4的版本。一个原因是网络发展的时间太久了,大家已经使用了数十年的IPv4了,所以现今存在的大部分网络设备都是采用的IPv4。另一个重要原因就是,IPv6无法兼容IPv4。因此如果想将I已经存在的全部网络设备从Pv4切换为IPv6,其需要付出非常巨大的代价,大家普遍无法接受。还有一个原因就是IPv6的发展时间并不长,所以稳定性还存在问题,比不上IPv4。因此现存的大部分网络设备都是采用的IPv4。
但是,IPv4提供的ip地址数量逐渐无法满足需求的现象也是客观存在的,所以现在越来越多的新出现的网络设备都开始使用IPv6了,而一些比较老的网络设备也在尝试从IPv4切换到IPv6。可以预见的是,在不远的将来,IPv6将替代IPv4成为ip协议中的主流版本。
端口号
注意事项两个不同的进程,不能绑定同一个端口号,但一个进程可以绑定多个端口号。了解:一个进程启动后,系统会随机分配一个端口(启动端口)程序代码中,进行网络编程时,需要绑定端口号(收发数据的端口)来发送、接收数据。进程绑定一个端口号后, fork 一个子进程,可以实现多个进程绑定一个端口号,但不同的进程不能 绑定同一个端口号。
认识协议
1. 语法:即数据与控制信息的结构或格式;类似打电话时,双方要使用同样的语言:普通话
2. 语义:即需要发出何种控制信息,完成何种动作以及做出何种响应;语义主要用来说明通信双方应当怎么做。用于协调与差错处理的控制信息。类似打电话时,说话的内容。一方道:你瞅啥?另一方就得有对应的响应:瞅你咋的!
3. 时序,即事件实现顺序的详细说明。时序定义了何时进行通信,先讲什么,后讲什么,讲话的速度等。比如是采用同步传输还是异步传输。女生和男生的通话,总是由男生主动发起通话,而总是在男生恋恋不舍的时候,由女生要求结束通话。
协议作用
知名协议的默认端口
五元组
在 TCP/IP 协议中,用五元组来标识一个网络通信:1. 源 IP :标识源主机2. 源端口号:标识源主机中该次通信发送数据的进程3. 目的 IP :标识目的主机4. 目的端口号:标识目的主机中该次通信接收数据的进程5. 协议号:标识发送进程和接收进程双方约定的数据格式
协议分层
在这一过程中,其实就存在两层协议。
第一层就是双方沟通时所用的语言协议,我们在这里用汉语沟通,就可以看成是汉语协议。通过这个协议,双方就能明白对方所要表达的意思。
第二层就是电话机协议。你和你朋友的电话之间要传输数据,为了让这两个电话能正确识别传输过来的信息并进行处理,就需要有一层电话机协议以让双方能够正确解析传过来的数据。
因此,协议分层实际上就是指在不同主机之间进行传输时,会将具有很强关联性的内容放在同一层,每一层都有一份单独的协议。
为什么需要网络协议的分层?分层最大的好处,类似于面向接口编程:定义好两层间的接口规范,让双方遵循这个规范来对接。通过协议分层,在我们对某一层进行修改的时候,就不会影响到其他层,且能实现不同的功能,在一定程度上达到 解耦。在代码中,类似于定义好一个接口,一方为接口的实现类(提供方,提供服务),一方为接口的使用类(使用方,使用服务):对于使用方来说,并不关心提供方是如何实现的,只需要使用接口即可对于提供方来说,利用封装的特性,隐藏了实现的细节,只需要开放接口即可。
例如在上图中,如果我们想用汉语,通过无线电沟通,就可以将通信设备层的协议修改为无线电协议;而如果我们想用英语,通过电话沟通,则只需要将语言层的协议修改为英语协议。这样不仅实现了解耦,还降低了修改成本。
所以,分层好处,一个是“解耦”,一层中出现了问题,不会影响其他层,能在不影响其他层的情况下更快速的定位错误;另一个是“封装”。在调整时,调整对应层中封装的内容即可。
在上面的例子中,仅仅分了两层。但在实际中,网络通信是非常复杂的,需要分为更多的层次。
在过去,大家可能以为在整个网络中都只使用同一个协议,这个认知其实是错误的。在网络中是进行了分层的,每一层都有一份对应的协议。
分层
在上文中说了,协议分层带来的好处就包括两方面,一个是“解耦”,一个是“封装”。总的来讲,其实就是实现了软件层面的“低耦合”。
而设计分层的依据之一就是:功能比较集中,耦合度比较高的模块。这些模块缠绕在一起,几乎无法分开。即具有“高内聚”特性的模块集合。
另一个依据就是,每一层都需要解决特定的问题。那这些问题是什么呢?在这里举一个旅游的例子来方便大家理解。
假设我们现在在上海,想去云南旅游。要实现这个目标,我们首先要考虑的第一个问题,就是我们如何从上海到达云南,是开车去,还是跟旅游团,还是步行?要从上海到达云南,需要经过一个又一个城市,并不是说我们嘴巴动一下,就可以直接从上海瞬移到云南,这之间是需要有方法和路径的。同样的,在网络中要将一台主机的数据传给另一个主机,首先需要解决的问题就是“如何将数据从一台主机传递给另一台主机”。
当我们决定好怎么去云南后,就要面临第二个问题了。整个中国这么大,交通路线众多,但我们在前往云南的时候,怎么确定我们的路线呢?这就要求我们在旅游的过程中,要有判断和选择路线的方法,或是看导航,或是询问路人。同样的,在网络中,一台主机加入的局域网或广域网中存在大量的主机和路由器,所以当一份数据在网络中传输时,这份数据要有路径选择的能力,选择前往目标主机的路径。
尽管我们在旅游的过程中可以依靠导航和询问路人的方法来选择路线,但是也可能出现导航出问题、或者路人记错路了的情况导致我们选择的路线出现问题。此时,我们就会可能原路返回或跟着这条路线去找其他的路。这就是我们在旅游的过程中,要有对路线的容错和纠错能力。在网络中,数据传输时也可能选择错误的路线,此时就要求数据有容错纠错的能力,比如让主机重新发一份。
解决了上面的三个问题后,我们终于可以顺利到达云南了。但是,到达云南是我们此行的目的吗?并不是,我们的目的是到云南玩,而到达云南,则只是实现玩这一目标的手段。因此,当一份数据被从一台主机传达到另一台主机的时候,就要求接收数据的这台主机,有利用这份数据解决应用方面的问题的能力。
总结起来,在网络通信中,一共需要解决一下四个问题:
(1)如何将数据从一台主机传输到另一台主机
(2)如何让数据传输的过程中拥有路径选择能力
(3)当数据传输出现问题时,如何让数据有容错或纠错的能力
(4)当数据成功传输到另一台主机中时,这台主机如何利用这份数据解决应用方面的问题
在这4个问题中,前3个问题都是为了实现成功传输数据的手段;最后一个问题则是为了解决数据应用的问题.
OSI七层模型
概念
上文中也说了,协议需要有一个可以话事的人来制定。所以,在国际中,为了有一个能让大家都遵守的规定,就有了“OSI七层模型”。
OSI(Open System Interconnection 开放系统互连)七层网络模型称为“开放式系统互连参考模型”,是一个逻辑上的定义和规范。
OSI七层模型把网络从逻辑上分为了7层,每一层都有相关、相对应的物理设备。比如路由器,交换机。OSI七层模型是一种框架性的设计方法,其最主要的功能就是帮助不同类型的主机实现数据传输。
它最大的优点就是将“服务”、“接口”和“协议”这三个概念明确的区分开来,通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。
模型形式
在OSI七层模型,它认为在网络传输中一共会遇到7个问题,所以它将这些问题划分为七层。在实际中的网络中,也确实会遇到这7个问题,但是在实际的工程中,我们并不会将这七层全部实现。
在OSI的七层模型中,第一层物理层是要解决硬件电路的问题,即比特流与电子信号的转换。
第二层数据链路层,其实就是解决我们上面提出的四个问题中的第一问题“如何将数据从一台主机传输到另一台主机”。
第三层网络层,主要做的就是地址管理与路由选择。在数据传输中存在大量的路由器和主机,它所要做的就是保证数据有“路径选择的能力”,即解决上面的第二个问题。
第四层传输层,就是用于判断数据在主机之间传输过程中是否丢失,当数据出现问题时如何解决。为数据提供容错纠错能力,即解决上面的第三个问题。
最后的会话,表示和应用三层,就是在解决上面的第四个问题。虽然这三层在逻辑上并没有问题,但是在工程实践中发现无法针对这三层提供一个放之四海而皆准的标准。由于这个原因,在实际中,便将这最后三层拍成了一层。而如何解决这三层的问题,便交由了用户,即程序员根据特定场景来自行实现。但是在实际编写代码的过程中,其实就是要实现这三层的内容,只是从模型上,将这三层拍成了一层。
所以,虽然OSI七层模型在逻辑上没有问题,但在实际中并不会采用OSI七层模型,而是采用TCP/IP五层(或四层)模型.
TCP/IP五层(或四层)模型
网络传输基本流程
协议报头
在上文中说过了,网络中是进行了分层的,每一层都有自己的协议。而每一个协议的最终表现就是,协议都要有报头。这个协议报头大家可能不是很了解,这里举一个例子。
假设今天我们从网上买了一个水杯,商家通过顺丰快递给我们发货。当水杯到的时候,我们去拿快递时,拿到的不仅仅有水杯,还有一个快递盒子和一张贴在上面的快递单。但是,我们从网上买的东西仅仅是水杯,并没有买快递盒子和快递单。这也就说明,在我们网上购物时,商家发货过来的东西并不仅仅是我们买的物品,还会多一部分。而这多出来的东西,其实就叫做“报头”。更准确来讲,这里的“快递单”才是“报头”。
但是顺丰快递是如何确保他们的快递员可以看懂快递单上的内容的呢?其实就是通过“格式”来实现的。例如快递单的左边是收货人的信息,右边是发货人的信息,通过这些规定,就可以让全国各地的每一个快递员都认识这个快递单上的内容。如果没有这些规定,就可能有人发货的时候就在快递单上写个张三,然后下面带一串数字。快递员看了怎么知道这些信息到底是收货人的还是发货人的信息呢?所以,协议通常是通过协议报头来进行表达的。
虽然在这个例子中只有快递站这个传输层,但如果在快递站之下又进行了外包,例如顺丰把快递外包给韵达,那么在韵达这一层也会一份快递单。即在网络传输中,每一份数据最终在被发送或者在不同的协议层中时,都要有自己的报头。
注意,虽然在现实中收快递时我们会接触和看到快递单,即快递站的协议报头,但这是现实中为了图方便省事和验货而导致的。在网络中,上层是看不到下层的协议报头的。即用户层是看不到快递站的协议报头的。
每一个协议的最终表现就是,协议都要有报头——报头在网络通信过程中起到关键作用,使得源和目的主机能够理解数据包的内容、目的地以及如何处理这些数据。
协议报头有如下三个特点:
(1)协议每一层都有,而每一个协议的最终表现就是就是“协议都要有协议报头”
(2)协议通常是通过协议报头来表达的
(3)每一份数据在被发送到在不同的协议层中,都要有自己的报头
数据包封装和分用
不同的协议层对数据包有不同的称谓,在传输层叫做“数据段”(segment),在网络层叫做“数据报”(datagram),在链路层叫做“数据帧”(frame)。
封装
引用层的数据通过协议栈发到网络上时,每层协议都要加上一个数据首部,即报头(header),称为封装(Encapsulation)。
首部信息中包含了一些类似于首部有多长,载荷(payload)有多长,上层协议是什么等信息。
数据封装成帧后就发送到传输介质上,到达目标主机后每层协议再剥掉相应的首部,根据首部中的“上层协议字段”将数据交给对应的上层协议处理。
分用
当数据被从一台主机传输到另一台主机后,这份数据就需要被对应协议层读走报头,然后将数据向上传输。而数据向上传输的过程就是分用。虽然在上文中的协议分层中每层协议层都是一一对应的,但是在实际上,每层协议层可能有多个上次协议层。
局域网通信
局域网,其实就可以看成是在同一台路由器下运行的主机组成的网络。在同一个局域网中的主机,是可以直接通信。即可以不通过路由器完成数据的传输。
在同一个局域网中的主机,可以看成是用网线连接起来的。假设现在有如下一个由七台主机组成的局域网:
假设此时mac1向mac7发送一条“你好”的信息,此时在这个局域网中的所有主机其实都看到了这条信息。但是由于mac1在发送信息时指定了向mac7发送,所以虽然其它几台主机都看到了这条消息,但是它们通过对比mac地址(MAC地址是网络设备的物理地址,它是唯一的,可以帮助网络设备进行自我定位。在同一个局域网(LAN)中,MAC地址可以用来唯一标识网络中的每一个设备)发现并不是向自己发送的,于是什么都不做。而mac7对比mac地址后发现是向自己发送的,于是接收这条消息。
通过上面的内容就可以知道局域网的数据是如何正确传输到目标主机了。但是,这两台主机在通信时,是如何通信的呢?首要要知道,因为协议分层的缘故,所以两台主机在通信时,势必要经过多层协议。
假设我们现在作为用户,向另一个人发送了一条“你好”的消息。这条消息首先会进入应用层,而应用层有自己的协议,所以此时就要添加应用层的协议报头。添加完成后,再这这份数据向下传输到传输层,传输层也有自己的协议,所以也要添加自己的协议报头,依次往下,每经过一层都要添加对应层的协议报头:
当数据在传输时,这份数据应该被叫做“报文”。最外层的协议报头被称为“报头”,而报头后面的内容,即后面的协议报头和要发送的信息被总称为“有效载荷”。即报文 = 报头 + 有效载荷:
当数据到达数据链路层后,这份数据就会通过以太网传输到另一台主机。当数据从一台主机被传输到另一台主机上时,并不是直接传输到应用层,而是传输到它的最底层,数据链路层。此时该主机的数据链路层会拿走最外层的协议报头,然后将剩下的数据向上传输到网络层。网络层再拿走最外层的协议报头,继续将剩下的数据向上传输,直到传输到应用层后,应用层拿走最后一个协议报头进行解析,最后将“你好”这条数据反馈给用户:
在这个传输过程中,用户A的数据向下传输添加协议报头的过程,就被叫做“封装”;而用户B中拿走协议报头进行解析过程,就被叫做“解包”。而将数据向上传输的过程,叫做“分用”::
通过上面的图我们可以发现,在同一层中,它们所拿到的数据都是一样的。所以在网路协议中,我们可以认为同层协议在直接通信,也可以理解成是向下交付的。
在有了上面的认知后,大家可能就会有如下2个问题。
(1)如何判断报头和有效载荷
(2)如何判断自己的有效载荷要交给上层的哪个协议。
这两个问题是每一层协议都需要面对的问题,都需要解决这两个问题。
其中一种解决方案就是,规定前多少字节为报头。假设规定传过来的前20个字节为报头,当上层接收到传过来的100字节数据,它就会去先读取前20个字节拿到报头,而后面的80字节就是有效载荷。而这份报头里面的前n个字节中的数据就包含了这份数据要向上层的哪一个协议传输。通过这种方式就解决了如何获取协议报头和如何知道这份数据应该向上层的哪一个协议传输。
广域网通信
广域网通信和局域网通信的方式是差不多的,唯一的区别就是在广域网中使用了路由器来完成数据包的转发,换句话说,路由器中一定存在两个或以上的网络接口来实现不同局域网的数据转发。
假设现在有以上两个不同局域网的主机要通信,左边的主机向右边的主机发送了一条“你好”的消息,这条消息同样会按照协议分层逐层往下传递,并在每层协议中获取协议报头:
当到达数据链路层时,这份数据就需要通过路由器转发到另一个局域网中的主机。此时,这份数据首先会传输到路由器中的驱动程序,即数据链路层,然后再这里进行解包,解包出的数据传递到路由器内,然后路由器再将其传到另一个驱动程序内并封装一层协议报头,再传到目标主机的数据链路层。即将数据传到路由器和将数据从路由器转发到另一台主机的过程中还要经历一次解包和封装:
如果大家观察仔细点,就会发现在上面的图中,左侧主机所处的是以太网,而右侧主机所处的是令牌环网。虽然它们所处局域网的标准不同,但是却可以没有阻碍的进行通信,这其实就是协议分层带来的优势,即“屏蔽底层网络差异”。通过在路由器中进行解包和封装的过程,就在无形中将以太网的标准替换为了令牌环网的标准,实现了双方的通信。
补充