网络原理概述
网络的历史
网络出现的背景及历史:通信学科
过去计算机刚发明的时候,一个国家都只有几台电脑,因此那个时候不需要进行跨计算机的沟通
随着计算机的发展,逐渐的,一些国家机构、企业、学校开始配备了电脑,然后发展到个人
跨主机的通信显得越来越重要
硬件通信
一个主机(host)可以分为两部分,分别是用户态和内核态
所谓的用户态和内核态,其实就是内存里的一块区域,从用户态转换到内核态是内存上数据复制的过程
内部的复制大致做了下面的工作
byte[] 用户态 = new byte[1024];// 待发送数据
byte[] 内核态 = new byte[1024];// 内核态缓冲区
os.write(用户态);
而网卡则作为数据的输出设备和输入设备,数据通过网络介质(就是上图的光纤)发送给另一个主机
网卡发送数据的过程:
- 将数据装入网卡,也属于数据复制,具体是否会装满看发射的数据
- 发射数据:比如调用fire()方法
- 发送需要进行数据信号到物理信号的转变
由网卡发射的数据在传输介质(如网线)上传播(可能会有信号衰退、信号差错等问题)
当数据传输到了另一台主机的网卡,会有一个引导,将数据引入CPU,当CPU被存满了之后,CPU会中断(即让CPU停止当前的执行循环),然后执行一段事先准备好的代码,每一个中断会有不同的信号,不同的中断编号会对应一个内存地址,CPU就会切换内存地址执行那段代码
这个中断流程做的事情就是把数据从网卡对应的位置复制到内核态的内存
然后内核态再次进行数据复制,把数据传入用户态
至此,两台主机之间只要能用一个网络介质连接,就可以从硬件角度实现数据交换了
网络通信
现实中,多台主机一起组网,如何实现数据的传输?
网络拓扑的基础构造,比如:总线型、星形、环形、树形
这些主机都通过某种基础结构连接在一个网络设备:集线器(hub)中
设备的作用:通过循环,把收到的信息复制然后发给其他主机
这些被直接连接在一起的网络,就被称为局域网(LAN local Area Network)
假设局域网被某个机构内部组成,而不同的局域网之间也需要进行通信
把这些局域网不断地组合起来,就是所谓的广域网(WAN Wide Area NetWork)
这里我们只关注局域网
协议/分层
要完成整个通信,中间要处理的问题还是非常复杂的。因此有必要进行分工合作
基本的分工:
网络分层就是把原来完成复杂工作而进行的分工合作
当有了分层之后,就需要针对每一层,都制定好一些规范,让大家都去遵守,进而更好地完成工作
这些规范具备一定的权威性,在网络学科中,将其称为协议(protocol)
网络标准分层
- 学院派:OSI(Open System Interconnect)提供了一个共7层的解决方案
- 实践派:TCP/IP 5 层协议(有时候称4层协议,即省略了物理层)
从上往下分别是:应用层、传输层、网络层、数据链路层、物理层:
- 物理层(Physical Layer):硬件角度保证数据转换/在网络介质中如何有效传播
- 数据链路(Data Link Layer):局域网内部一台主机和另一台主机连接通信的问题(冲突域、广播域)
- 网络层(Network Layer):实现数据路由的功能基础上,最终实现跨LAN的主机到主机间通信的问题
- 传输层(Transmission Layer):实现主机上任意进程至另一台主机上任意进程通信的问题
- 应用层(Application Layer):实现应用自己的业务问题(业务不同,协议不同)
3个重要的网络设备(Network Device),注意:这些网络设备不是主机
- 集线器(hub)
- 交换机(switch - sw)
- 路由器(router)
我们需要知道这些网络设备工作在哪一层,以及各自的工作职责是什么(即为了解决什么问题而存在的)
主机间的通信
第一种情况:两台主机直连(没什么讨论的必要性)
我们主要讨论第二种情况:带有一定拓扑的局域网
集线器和冲突域
集线器可以有效地解决网络拓扑中数据传递的问题,集线器工作在物理层(两个功能:1.复制数据;2.信号放大)
假设一个场景:
老师说:张三,请你问答一个问题
这句话所有同学都能听到,但是只有张三会做出回应,因为我们传送的数据中带有目标地址“张三”
但是在教室中,人人都可以主动说话,导致互相之间都听不到对方说话,这就是冲突域
同样的,主机之间在共用一个信道,而信道一次只能走优先的信号,导致信号会在信道上出现冲突
换言之,使用集线器进行组网,天生就处于同一个冲突域,这是集线器的工作原理导致的
如果已经在同一个冲突域下,要如何解决:通过一定的冲突避免算法,进行冲突避免 - 由数据链路层取解决
最常见的一种冲突避免算法:发现冲突之后,静默随机时间,再次发送
即使有冲突避免算法,使得冲突域内的数据可以有效传输了,但是信号传输效率还是会受到影响
因此,使用集线器需要注意:
- 冲突域内的主机不要太多
- 尽可能减少冲突域的出现
交换机
集线器的工作只是数据复制,根本不知道数据是什么
而数据中带有目标地址,我们可以使用交换机来尽可能避免冲突域的问题
交换机需要理解数据链路层放入的目标地址(需要能解析数据链路层协议),根据数据的目标地址,决定把数据给谁
交换机工作在数据链路层,其目标就是根据目标地址将数据一对一地传输给对应目标
所以,通过交换机,也可以组建局域网,各个主机之间就没有了冲突域
注意,使用交换机并不是完全没有冲突域,只不过交换机把冲突域划分为各个主机了,每个主机有一个冲突域,比如很多主机都给某一台主机发送数据的时候依然会有冲突,只不过这些冲突都只会发生在一个主机上,而集成器的冲突域只要是连接在集成器内的主机,全都处于一个冲突域,任意主机发送的数据,每个主机都会收到
因此有的时候我们会听到一句话:交换机是用来划分冲突域的
广播域
单播的目标地址是一台主机,广播的目标地址则是一个特殊地址
但是世界上的主机太多了,不可能实现一个主机发出的数据,世界上所有的主机都能收到
因此就将主机划到各个区域,每个区域都是一个广播域
广播域之间也能相连,通过路由器连接
MAC地址
数据链路层的地址指的是MAC地址(物理地址)
MAC地址的长度为48位(6字节),通常表示为12个16进制数,如:00-16-EA-AE-3C-40,这就是个MAC地址
网卡产生的时候该地址就写死了,可以说,全世界的网卡的MAC地址是不会冲突的
其中,地址FF-FF-FF-FF-FF-FF作为广播地址使用
交换机解析到地址是广播地址的时候,就会把数据复制并发送给所有的主机
经过以上内容的介绍,一个LAN内部,无论哪种设备,哪种拓扑,主机和主机都已经可以正常的通信了
主机与主机之间的通信是数据链路层的职责,接下俩看上一层,即网络层
网络层
通过数据路由,解决跨LAN的主机间通信问题
路由器就是工作在网络层的,路由器至少处于两个局域网(至少有两张网卡)
一个局域网内的主机发出数据,数据经过路由器处理,然后路由器发送给另一个局域网中的主机
没有路由器的时候,数据只能在同一个LAN传输,而路由器横跨两个LAN,所以,跨LAN的传输是需要经过路由器传递的
路由
路由(route):主要是为了完成寻路工作
路由器(router):用于完成寻路功能的一种设备
数据可以经过不同的路线到达其他局域网,因此需要专门的寻路设备来进行找路的工作
网络层的协议是为了完成寻路,实现跨LAN的主机到主机
网络层也有自己的地址,即IP地址
IP地址
IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)
如: 01100100.00000100.00000101.00000110。
通常用“点分十进制”的方式来表示,即 a.b.c.d 的形式(a,b,c,d都是0~255之间的十进制整数)。如:100.4.5.6。
IP地址是软件地址,同一个网络内部的IP地址是不应该“重复”的,且IP地址随时变化的
127.0.0.1表示自己的主机(localhost)
由于IP地址并不好记忆,因此使用域名比较多,比如www.baidu.com
,域名解析之后就是IP地址
五元组
在TCP/IP协议中,用五元组来标识一个网络通信:
- 源IP:标识源主机
- 源端口号:标识源主机中该次通信发送数据的进程
- 目的IP:标识目的主机
- 目的端口号:标识目的主机中该次通信接收数据的进程
- 协议号:标识发送进程和接收进程双方约定的数据格式
传输层
无论是否跨LAN,总之主机到主机之间的通信经过数据链路层和网络层已经全部连接起来了
那么同一主机中进程和进程之间也需要通信,实现进程间的通信也需要一个类似地址一样的东西,因此就有了端口
端口(port) :范围在0 - 65525之间的两个字节的无符号数
进程可以用端口号来表示,写明端口,就能对应到具体的进程
一个进程可以有多个端口(不冲突),但一个端口只能分配给一个进程(不能重复)
至于剩下的应用层属于业务逻辑,这里不讨论
以上内容的总结就是:
应用层通过代码实现,所以属于用户态,而传输层、网络层以及数据链图层不需要写用户关心,所以属于内核态
一些重要的协议:
- HTTP/HTTPS/DNS 属于应用层
- TCP/UDP 属于传输层
- IP 属于网络层
通信过程中数据的处理
同一个LAN内部,应用层(进程)to 应用层(进程)的过程:发送时进行封装,接收时解包 + 分用
关于封装:
- 不同的协议层对数据包有不同的称谓,在传输层叫做段(segment)或报文(datagram),在网络层叫做数据报 (packet),在链路层叫做帧(frame)
- 应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装 (Encapsulation)
- 首部信息中包含了一些类似于首部有多长,载荷(payload)有多长,上层协议是什么等信息
- 数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,根据首部中的 “上层协议字段” 将数据交给对应的上层协议处理
信息发送前,从上往下经过各个层时会进行封装:
需要传输的数据:“hello”
传输层:添加该层协议相关的控制信息后:"src: 源端口号, dest:目标端口, hello ",前面部分称为header(首部),后面发送的数据内容称为payload(负荷)
网络层:“src: 源IP地址, dest: 目标IP地址, src: 源端口号, dest:目标端口, hello”
数据链路层:“src: 源MAC地址, dest: 目标MAC地址, src: IP地址, dest: IP地址, src: 源端口号, dest:目标端口, hello”
经由网络介质发送的实际就是经过数据链路层处理后的数据信息,这个不断增加数据信息的过程就是封装
而另一台主机接收到信息之后,对这些信息进行解包,拿到传输过来的数据
“src: 源MAC地址, dest: 目标MAC地址, src: IP地址, dest: IP地址, src: 源端口号, dest:目标端口, hello”
“src: 源IP地址, dest: 目标IP地址, src: 源端口号, dest:目标端口, hello”
"src: 源端口号, dest:目标端口, hello "
“hello”
这个过程中,各层只获取各层需要的信息,其他数据会由各层自己处理
至此,封装 + 解包实现了以下两点:
- 各层可以根据各层自己添加的控制信息进行必要的操作
- 对应层次之间是完全透明的,完全可以忽略中间的其他过程
除此以外,控制信息中需要携带分用信息,用来指导,数据应该交给上层的谁
比如,货物运输到货站之后,各个代理人或物流公司前来取货,将货物给到对应的代理人或公司手中的过程就是分用
总结:
发送:封装(必须携带分用和解包信息)
接收:解包 + 分用(根据本层的控制信息)
跨LAN的应用层(进程)to 应用层(进程)的过程
当一个主机1要跨过LAN1和LAN2两个路由将数据传输给另一个主机2时,这属于应用层
然后信息进行封装:
-
传输层:“src: 端口号1 dest: 端口号2, 数据内容”
-
网络层:这一层比较特殊,需要牵涉两个概念,即长期目标和短期目标
长期目标就是最终目标,在这里就是主机2 ,信息封装:“src: 主机1, dest: 主机2”
短期目标就是同一个LAN的目标,需要根据长期目标计算得出,在这里就是LAN1,信息封装:“src: 主机1, dest: LAN1”
当到达LAN1之后,短期目标已经到达,重新根据长期目标计算新的目标是LAN2
到达LAN2之后,再次计算新的目标,由于此时主机2已经在LAN2中的一个局域网了,因此短期目标就是主机2
经过不断地解包 + 分用,最终主机2收到了数据内容,交给应用层处理数据
这一过程中,这些点要重视:
- 长期目标和短期目标的区别
- 数据经过路由器再传达,且路由器懂得网络协议(看得懂长期目标,并能动态计算短期目标)
- 数据链路层的数据不断被解包然后封装,这是因为长期目标和短期目标都在网络层,数据的解包是逐层进行的,因此处于较低层次的数据链路层就会不断地解包又封装
我们平时使用的网络: