作者:@小萌新
专栏:@网络
作者简介:大二学生 希望能和大家一起进步
本篇博客简介:简单介绍网络的基础概念
在计算机发展的早期是没有网络的 计算机是作为一个单独的计算工具来使用
可是慢慢人们发现 如果只是单纯的这样使用计算机 那么数据在各个计算机之间的流转就会十分的效率低下
这时候就有人想办法 将这些计算机连接起来 当某些业务需要互联的时候人们就将这些数据上传到一个共享服务器 来实现数据的共享
再后来随着网络的发展 连接进入网络的机器越来越多 于是就出现了局域网的概念
在局域网中有一种设备叫做交换机 交换机主要完成局域网内数据的转发工作 也就是在局域网内将数据从一台主机转发给另一台主机
各个局域网之间通过路由器连接起来,路由器主要完成数据的路由转发工作
随着接入的局域网不断的增多便形成了广域网
但是实际上广域网是一个相对的概念 我们可以将广域网理解为一个较大的局域网
关于城域网和校园网的概念 我们也可以将他们理解为一个较大的局域网
我们在前面讲解操作系统的时候我们一般将操作系统分为下面这几层
我们在之前讲过一切皆文件的概念 事实上这个概念也可以让我们来理解网络为什么可以分层
拿STL的例子来说 我们编写了一个程序 调用了STL库
我们在写自己的代码的时候并不需要去关心STL库是如何实现的 这也就说明了软件是可以分层的
同样的 网络也是软件 所以说软件也是可以分层的
其中
所以说我们现在可以回答网络在哪里
这里的网络指的是网络协议栈 它是一个软件 贯穿体系结构的tcp/ip 属于操作系统的一部分
协议的本质就是约定
在大概十几年前的时候电话费是非常贵的 此时一个学生去上大学 他因为负担不起高昂的电话费便和家里做出了如下的约定
该学生每晚九点会往家里打一个电话
上面我举的这个例子就是一个协议
另外我们应该都知道 计算机之间的传输媒介是光信号和电信号 通过“频率”和“强弱”来表示0和1这样的信息 因此要想传递各种不同的信息 就需要约定好双方的数据格式 这就是一种纯硬件的一种约定方案
协议本身是需要标准的
比如说你现在在家里 跟你的家人说你饿了想要吃饭 那么这个时候你的家人就会按照以往约定俗成的协议来给你做饭 但是如果你说 im hungry 你表达的意思也是自己肚子饿了 但是你的家人却不能理解这是什么意思 导致你还是饿肚子 这就是没有标准协议所造成的坏影响
协议应该由谁来制定
在当前这个互联网时代 计算机生产商有很多 计算机操作系统也有很多 计算机网络硬件设备更是多种多样 那我们是如何让这些不同厂商之间生产的计算机能够相互顺畅的通信的呢 这时候就需要有人站出来 约定一个共同的标准 并且让大家都来遵守这个标准 这就是网络协议
而那个站出来的人一定是该领域当中的佼佼者 因为网络协议的定制本质就是规则的定制 你要站出来制定规则那么一定要同行业的其他人都认可你 比如5G标准的定义 华为就是那个站出来的人 华为在通信领域已经具备很强的通信能力了 在这个行业里它就是所谓的佼佼者
正所谓“一流的企业做标准 二流的企业做产品 三流的企业做技术” 但是标准的定制有一部分是公益性、开源性的 它制定标准的目的是为了让我们的世界变得更好 而标准的定制还有一部分是具有一定盈利性质的 当你需要使用这项技术时就会收取部分专利费 此时就能将曾经做的技术投入进行变现
为什么协议要分层
我们之所以要设计层状结构目的就是为了将层与层之间进行解耦
拿打电话来说 其实打电话也是一种层状结构
在语言层上我们通过汉语来沟通 在通信设备层上我们通过座机这个设备来沟通
随着科技的发展 我们可能都不会使用座机了 而是使用手机 这就是我们的通信设备层改变了
又或者说我们移民到其他国家开始说英语 这个时候就是语言层改变了
总之 分层之后替换某一层的协议之后打电话这个行为并不会受到影响
各层直接通信
在上面的例子中 虽然打电话时我们并不是直接进行沟通的 但是我们可以认为自己是在直接进行沟通
并且这两台电话也不是直接在进行沟通的 数据经过电话后 还需要各种基站 各种电信网络来进行数据转发 但是这两台电话依旧可以认为是直接在和对方电话进行通信的
因此对于网络协议我们需要有一个基本的认识:关于通信 同层协议可以认为自己在和对方层直接进行通信 从而达到简化对于网络协议栈的理解
也就是说 在网络协议栈中我们可以认为通信双方的应用层之间直接在进行通信 也可以认为通信双方的传输层之间直接在进行通信 对于网络层和数据链路层也同样如此
我们最开始制定的协议叫做OSI协议 这个协议一共分为七层
其模型如下
TCP/IP是一组协议的代名词,它还包括许多协议,共同组成了TCP/IP协议簇。
TCP/IP通讯协议采用了五层的层级结构 每一层都呼叫它的下一层所提供的网络来完成自己的需求
我们使用包裹传输作为例子解释下TCP/IP协议
假设我们的用户现在买了一个洗面奶 现在卖家开始发货 它的发货路线是从上海发到福建再到江苏最后到用户手上
其中从卖家到上海 从上海到福建这一跳一跳的过程就是由数据链路层决定的
而为什么要选择上海–福建–江苏这条路线 而不是选择其他路线这是由网络层决定的
从上海发到福建的过程中保证快递不丢安全送到这是传输层保证的 传输层保证安全性
最后我们花费了这么多的力气从卖家送到用户手里并不是送到就完事了 用户肯定还要使用这个洗面奶 如果不知道怎么使用肯定还要继续问卖家 而这一步则是应用层的任务了
总结下 下三层保证了数据了传输 而最上层保证了用户的使用
我们可以抽象的认为 物理层就是硬件层 数据链路层就是驱动层 当然这个理解并不完全正确
与OSI七层模型各层的对应关系:
可以看到 它们的下面几层几乎是没有区别的 操作系统对应的是传输层和网络层 数据链路层和物理层都是对应在驱动层的 而TCP/IP协议当中的应用层就对应到OSI七层协议当中的应用层 表示层和会话层
一般而言:
但这并不是绝对的 比如很多交换机也实现了网络层的转发 很多路由器也实现了部分传输层的内容(比如端口转发)
集线器
就像我们的声音会随着距离的增加而减弱一样 电磁信号在长距离传输过程中信号是会衰减的 所以说集线器被发明出来了
集线器的主要功能就是对接收到的信号进行再生整形放大 以扩大网络的传输距离 同时把所有节点集中在以它为中心的节点上
需要注意的是 集线器属于纯硬件网络底层设备 基本上不具有类似于交换机的“智能记忆”能力和“学习”能力 也不具备交换机所具有的MAC地址表 所以它发送数据时都是没有针对性的 而是采用广播方式发送 也就是说 当集线器要向某节点发送数据时 不是直接把数据发送到目的节点 而是把数据包发送到与集线器相连的所有节点
我们这里以两台主机进行文件传输为例,此时各层对应的协议如下:
首先第一个问题 局域网是可以直接通信的嘛?
答案是可以 同一个局域网内的主机是能够直接进行通信的
这里有两个具象化的例子帮助大家理解一下
在连不上互联网的情况下 我们家里的电脑和路由器还是可以直接通信的 因为它们两个是属于同一个网段的
我们玩一些游戏比如说cs这些不需要互联网 同一个楼层的朋友也可以使用局域网进行联机
局域网通信原理
在同一个局域网中很多个主机 那么A主机是怎么做到跟B主机通信的呢?
我们可以将这个场景抽象为一个在教室中的场景 在教室中假设你是一个老师 现在你开始质问张三 “张三 为什么你昨天的作业没有交” 这个时候张三站起来回答说“老师 昨天身体不舒服 所以没做 ”
我们回头看刚刚这个场景 为什么我说了一句话张三就站起来了呢? 大家可能觉得这个问题很笨 因为我叫的是张三的名字啊 那为什么其他同学听到之后没有站起来呢? 因为我没有叫其他同学的名字啊 那么其他同学听到我说话了嘛? 答案是听到了 这其实就是局域网通信的原理 广播自己说的话+接受这个话的对象 其他人虽然都能听到但是知道这个信息不是给自己的所以都丢弃了
反应到计算机中 每一台主机都有自己的mac地址 在A主机发送的这个消息的报头中携带了一个B主机的mac地址 所以说只有B主机收到这个消息之后解包了 其他主机收到之后看mac地址不是自己的便丢弃了
数据碰撞
回到我们教室的例子中 教室是一个公共资源 所以说大家都可以使用 那么在我向张三说话的时候李四有没有可能也在说话呢?
答案当然是有可能的 如果大家的声音都很大的话那么我们就听不清别人发送给我们的信息了 这就叫做数据碰撞
但是消息不能因为数据碰撞就不发了啊 所以说每一台主机都必须要有数据碰撞算法 当检测到数据碰撞的时候等一段时间再发送(每台主机的等待时间不一样)
如何判断发送出去的数据是否发生了碰撞?
因为发送到局域网当中的数据是所有主机都能够收到的 因此当一个主机将数据发送出去后 该主机本身也是能够收到这个数据的 当该主机收到该数据后就可以将其与之前发送出去的数据进行对比 如果发现收到的数据与之前发送出去的数据不相同 则说明在发送过程中发生了碰撞
也就是说,主机实际是能够通过某种方式 知道曾经发送出去的数据是否发生了碰撞的
如果我们拿操作系统的理解去理解网络的话 实际上网络(局域网)就是一个临界资源 它是要保证互斥的
如何攻击网络
既然上面我们知道局域网是互斥的且没有同步机制攻击的思路就很简单了 我们只要解除计算机的数据碰撞算法 让一台计算机不停的网局域网中发送垃圾信息那么所有的计算机就都不能通信了
我们将TCP/IP四层协议抽象成四楼
假设你现在在左边的四楼 而现在你老师要求你将一份文件送给右边四楼401的一个老师 那么你应该怎么送过去呢? 直接飞到右边的四楼嘛? 显然不现实
那么下到三楼之后再飞到对面的三楼嘛? 显然也不现实 你应该做的是 现在开始下楼到达一楼之后走路到对面的一楼 之后再慢慢爬上四楼将文件交给401的老师
用网络的视角看是这样子的
当用户要将文件传输给另一台主机前 该文件数据需要先通过网络协议栈进行封装:
数据封装完毕后就可以通过局域网将其发送给对端主机了,而当对端主机收到数据后,对应也需要通过网络协议栈对该数据进行解包与分用:
也就是说,任何一台主机在发送数据之前,该数据都要先自顶向下贯穿协议栈来完成数据的封装,在这个过程中,每一层协议都会添加上对应的报头信息;而任何一台主机收到数据后,都要先自底向上贯穿协议栈来完成数据的解包和分用,在这个过程中,每一层协议都会将对应的报头信息提取出来。
画出上面传输协议的图 表示如下
画出这幅图之后我们能够惊奇的发现一个现象 同层所看到的数据是相同的
我们在上面解释通信过程的时候多次提到报头 那么什么是报头呢?
还是拿我们上面快递传输的例子来讲 卖家在发快递的时候不是只把货包装一下就好了 一般来说还会附带这样子的一个快递单
(图片来自网络 侵删)
这个快递单我们就可以将它理解为报头
它记录了是谁发送的快递 应该发送到哪里 地址是多少
它指导当前层进行某种协议决策
我们在计算机中如何理解报头和有效载荷呢?
在上图中 红笔画上下划线的就是报头 其余的数据便是有效载荷
首先我们要知道报头是一个数据 而linux是用c语言所写的
所以说报头在linux中其实就是一个结构体 更准确的来说就是一个位段
如何理解计算机中的数据封装和解包
我们上面说过封装实际上就是加上报头 而在计算机中封装实际上就是开辟出一块新的缓冲区 然后先拷贝本层的报头数据之后再拷贝有效载荷
解包也是一样 开辟出一块新的缓冲区 然后使用一个指针指向数据的开始 将这个指针强制转换成本层报头的类型++之后将后面的数据拷贝到新缓冲区 这就叫做解包
报头中的数据
几乎每个报头中都要含有两个数据
如果之前了解过网络的同学可能会知道tcp旁边还可能有个udp协议 那么ip协议往上应该传送给哪个协议呢? 报头中的数据规定了这一点
此外有个网络的协议非常的多 所以说报头会明确自己和有效载荷的边界以防少传或者多传导致信息错误
两台机器的跨网络通信如上图所示 为了让大家更好的理解我们先来解释几个概念
IP地址和mac地址
拿西游记的故事举例 比如说唐僧路过车迟国 现在在跟车迟国国王交流
国王问唐僧从哪里来 唐僧说 从东土大唐来到西方去取经
国王又问你上一站从哪里来 下一站准备去哪里呢? 唐僧说 上一站从女儿国来 下一站准备去黑风岭
我们可以发现 这里唐僧其实说了两套地址
上面这个一直不变的地址我们就将它叫做ip地址 下面一直改变的地址我们就叫做mac地址
再来看这张图 比如说现在要一个数据从左边的网络层要发送的右边的网络层 它中间要不停的经过封装解包的过程 而此时它报头中的mac地址是一直不停变化的 因为它的上一站和下一站在不停的变化
而经过IP层之后我们看不到下层的任何差异了 即IP层屏蔽了下层的所有差异
如何在Linux中查看自己的MAC地址?
我们可以使用ifconfig命令可以来查看当前主机所对应的网卡信息
该地址就是我们的mac地址 但是由于我们是租用的云服务器 所以说这个mac地址不是真正的mac地址 而是被模拟出来的