Linux操作系统学习之---初识网络
网络的产生:
抛开计算机的语境 , 网络无非就是一根根纵横交错的线 , 交织出连接了一个个的点 . 而每一个点就是一个个相互协作的计算机(人)。
学习操作系统时 , 冯诺依曼体系结构是一切的基石 . 但是仔细想想 :数据从磁盘到内存,再到CPU , 处理完后又返回给内存 ,继而通过外设(如显示器)让用户觉察 。这个过程 ,在一台本地笔记本电脑内部不就是一张网吗?其中的个体就是这一个个硬件,之间由线连接(比如IO总线)。各个硬件相互协作 , 通过这一条条线传输数据 , 就处理好了上层用户的数据!!!
对于网络也是同理 。为什么需要网络,因为人类的历史就是协作的历史。作为生产力工具的电脑自然也要跟上人类协作的脚步 ,那怎么实现协作呢?原始的方法是每个人把自己的数据处理完,用各种便携式的存储设备拷贝数据拷贝的同一台电脑上,但是太麻烦了!!!
11路生物能车(人的双腿)效率太低,我们选用更快的光(电磁波)来通信。有这样一段奇闻轶事:早些年物理学界存在一个争论:光的传播是否需要介质?支持的一方把这个介质取名为以太。但是最终这个概念被证伪。因此计算机界实现基础的局域网后就把这种计算机之间通信的介质取名为以太,这种网络就叫做以太网。
网络协议:
- 想象两个人之间通过电话通信,往往都是互相“喂”一声,通过这个声音本身知道电话已打通,通过对方的声音判断是不是熟人。第一句话说啥,用什么语言,这就是人之间的协议
- 计算机之间通信也需要类似的约定——就称为协议。并且计算机只认二进制,所以得规定用同样的方式来表示二进制,比如都是电磁波的波峰表示‘1’、波谷表示‘0’,以此避免产生歧义。用什么方式表示什么信息,这就是计算机间网络通信的协议(不止于此哈)
凡是比较底层的技术,都会存在协议的制定,在协议的基础上实现的技术才能称为计算机间的黑话来互相交流。制定网络协议的组织叫做ISO(国际化标准组织),其制定的协议叫做**OSI(开放系统互连模型)**分为七层 :
网络协议就是计算机之间的约定,可以解决成本和提高效率
下面的图看个热闹就好,因为OSI协议里规定的这七层往往无法全部实现,不是因为他定的不好,而是因为他设计的太好了,面面俱到,可以满足个性化的需求。操作系统实际的实现里用的最多的是TCP|IP协议,他分为五层:应用层、传输层、网络层、数据链路层、物理层,其中将ISO七层协议里的上三层合并为了一个应用层。

协议分层:
上面的图里可以明显的发现,协议是一层一层来的,这个时候其实很容易联想到另外一张图:计算机体系结构的分层!!!如下:
要知道,两台计算机进行网络通信的硬件基石就是网卡,而网卡作为底层硬件属于操作系统体系结构的最底层。因此,网络就是操作系统的一部分!!!
操作系统也是一个软件,统筹管理软硬件资源。分层的核心目的就是各个层次之间的解耦合,这样每个层次自己的修改不会影响其它层,因此层次之间只关心互相之间的数据流动。
网络同理,各个层次之间的解耦合使得开发和维护都更加的方便。更加直白的理解就是:上层用户只管通信,下层的软件和硬件层只管好好设计功能。未来即便换了底层的具体软硬件实现,对上层用户来说无感知,对于底层开发者来说可以每一层独立更换、升级和问题排查,更加有助于人之间的分工协作!!!

[!不同操作系统间能够网络通信的原因]-
不同的操作系统虽然各不相同,但是只要网络部分的涉及遵守同样的协议,自然就能通信啦。
协议产生的深层次原因:
在最开始网络产生的部分我们说到计算机内部的各个硬件共同构成的就是一个网络 ,只不过在电路板上用实实在在的线(如IO总线)相连。
现代计算机高度的集成性使得各个硬件间“通信”的距离很短,但是网络要求的是跨越地域的通信,当通信的距离拉长,问题就产生了!!!协议就是为了解决新问题而产生的。每一层就是对于一个问题的解决方案
| 计算机内部硬件间的“通信” | 计算值与计算机间的网络通信 | |
|---|---|---|
| 数据用来干嘛? | 用线相连的两头硬件减天然就知道 | 应用层来保障 |
| 数据丢了怎么办? | 顶多就是线的电阻,但距离很短所以忽略不计 | 传输层来保障 |
| 数据送往哪里? | 相连的线就是最好的指南针 | **网络层(IP)**来保障 |
| 数据当下应该去往哪里? | 相连的线都规定好了 | 数据链路层来保障 |
进一步理解协议:
网络属于操作系统的一部分,而操作系统又是c语言实现的,因此网络同样需要被操作系统用结构体(struct)描述起来,这样就能方便协议的实现。
只要遵守相同网络协议两个操作系统使用同样的结构体来描述网络 ,就能实现数据互传啦。一个个的结构体对象,实际上就是协议的具象化
假设传输层是这样一种结构体:正确的处理方式是a+b-c
struct protocol {
int a;
int b;
int c;
};
那另一台计算机收到这个结构化的数据后就可能按照协议规定的数据解析方式来获取数据。
[!通过快递包裹来理解协议]-
比如我们网购一部手机时期望的只是手机相关的硬件,但是收到的物品却由一个纸盒子包裹。盒子上又有许多信息:
- 寄件人:类似于发消息的计算机
- 收件人:类似于接收消息的计算机
- 地址 :类似于决定数据最终去向的网络层
这一个个的信息就是协议的内容,计算机在传输数据的同时也得带上这些信息,最终就能实现数据的传输。
网络传输的基本流程(局域):
- 既然网络的发展趋势是局部到整体,那先从局域网的传输谈起。(起始广域网依然是建立在局域网的基础之上的哈哈哈)
- 网络传输的目的是让计算机之间实现通信,嘿嘿,是否想到了进程间通信的本质——看到同一份资源,网络通信也是类似的原理,只不过形式不同。
局域网的由来:
局域网的标准有很多,比如: 以太网、无线LAN、令牌环网。之所以有着许多类型,是因为早期的局域网真的就是在局部的那一亩三分地,比方说各个国家的顶尖研究所里都有各自的局域网来方便自己人进行信息交换。
就好像最开始人类的贸易往来局限于国内和同大陆的国家之间,但后来发展到跨洲和跨洋,这是航运技术进步的必然结果。计算机也是如此,网络技术的进步就使得计算机可以跨洲和跨洋交流。
以太网:
首先提出一个结论 : 两台主机在局域网内可以直接通信,通信的手段类似于进程间通信:看到同一份资源,每个主机也会有唯一标识符:MAC地址.
想想这样一个场景:一个教室里有一个老师和许多学生1、老师喊张三起来回答问题,张三站起来了,原则上回答的过程中李四和王五不许插嘴,因为老师制定了张三的身份。(MAC地址)
2、但是李四和王五实实在在的可以听到老师和张三的对谈(信息泛洪)
3、因此受到干扰后,李四和王五想要专注于自己的事情不容易(数据碰撞)
4、这个教室就是一个充满干扰的环境(碰撞域)
泛洪:
计算机通过电磁波来传递信息,但是想想一片平静的湖面,如果你扔一块石头,会发现波纹是自中心向周围扩散。如果是多块石头,就会发现波纹和波纹之间交织的图形混乱不堪。这就是多台计算机在交流时会发生的问题——泛洪:**大家都在发送扩散式的信号,每台机器都会收到所有人发出的消息
可是计算机之间往往是点对点的通信,必须要知道那个消息是发给自己的,这是就需要一个标识符(下面的MAC地址)来进行区分了。
MAC地址:
每一台电脑的网卡在硬件设计时就自带了一个MAC地址,作为网络通信时的唯一标识符,由48个比特位表示。
Linux下查看MAC地址(图中的ether):

通信依据:
计算机左手电磁波(寄件手段),右手目标MAC地址(收件人),就可以让符合MAC地址的其他计算机接受并处理这个消息了。
[!抓包工具的运作]-
所以为啥抓包工具能够存在呢?因为传输的资源在局域网内所有计算机都可以看见,只不过没有抓包工具时每台计算机都是乖孩子,不看别人的东西(严重批评某大学外卖总是被偷!!!就该送到手别人其他人中途看见)。
#Linux/网络/抓包工具的底层原理
碰撞域:
补充一个概念碰撞域。即在同一局域网的一片空间里这片区域,由于各个计算机的电磁波信号不分青红皂白的四处扩散,最终交织碰撞。这片区域就叫做碰撞域。
碰撞的常见处理方法
- 碰撞检测(collision detect) : 将自己发送出去的信息和原信息对比,如果不一致,说明在发送的过程中和其他计算机的信息产生碰撞,造成数据丢失。
- 碰撞处理(collision avoidance): 一旦检测到碰撞产生,立马随机停止发送信号。由于是随机,可能局域网内的各个计算机就实现错峰传输了。
临界资源:
一台计算机通过局域网发出的信号:
- 可以被所有计算机看见。
- 但是被其他计算机贸然修改会出问题(发生碰撞)。
所以,这不就是多线程中临界资源的概念吗?每台计算机就好比一个执行流,一起竞争以太网这个临界资源。
想要避免这种情况产生使用的错误处理,也就类似于加了一把锁,让一段时间内只有一个计算机可以传输信号,从而实现互不干扰的串行。这样的锁是乐观锁,先发送消息了再说。
但是,线程实实在在的处于一台计算机里,可以通过共享的内存资源来间接的了解其他线程的状态,从而在源头上避免同时访问临界资源的问题。
无线LAN:
无线LAN也是局域网的一种,只不过客观来说范围比以太网大。
网络传输发生在计算机之间,彼此之间是谁、以及处于什么状态都是不可提前预知的。所以这就是为啥同一个地方如果使用网络的人多了,网速就会变慢,因为更多的手机(此时往往使用的无线LAN)就会触发更多的碰撞检测,从而在更频繁的碰撞处理的影响下网络信息迟迟无法递送,最终体现在用户的应用层就是网速变慢了。
令牌环网:
同样是局域网的一种,但是实现方式上类似于执行流之间的互斥。
——想想你在一个人声鼎沸的大操场上看节目表演
1. 周围环境很吵,你连身边人的声音都听不见。
2. 但是持有麦克风的主持人就可以发出振聋发聩的声音。
3. 如果有人也想向全场表达自己的观点,必须拿到麦克风后消息才能传达,否则没有说话的必要!
上面的例子里,可以理解为持有令牌的主机才能发送消息。
协议栈:
层次结构:
网络协议的分层结构和计算机体系结构的分层惊人的相似,因此可以通过类比来从宏观操作系统的理解到局部网络的理解。
计算机体系结构
当程序执行一个诸如
printf的系统调用函数时,在计算机里必定要贯穿体系结构的各个层次。
- 用户层:对
printf进行系统函数调用。(系统调用函数也是用户层的程序员编写的。)- 操作系统层:系统调用函数里的相关指令(如syscall)触发陷阱,操作系统保存当前进程上下文,转而带着系统调用号和参数陷入内核,查系统调用表,开始进行回调。
- 驱动程序层:根据不同的函数,调用不同硬件的读写方法。
- 硬件层:通过中断控制器等硬件接收到操作请求。
网络协议栈:
至于为什么叫做“栈”,等下就会知道,但毕竟栈也是一个一个入一个一个出的嘛,一层一层的也好理解。现在只是浅浅的涉猎一下这个层次贯穿的过程。
- 应用层:用户期望发送的数据在应用层。
- 传输层:保证数据能够正常传出去。
- 网络层:让数据知道自己最终该去往何处。
- 数据链路层:让数据知道自己当下该去往何处。
- 物理层:就是计算机内部的网卡和外部硬件(如路由器)的交互。
因此,只要使用网络发送数据,一定会贯穿这个层次结构
反过来,只要是通过网络接收数据,一定会自下而上贯穿这个层次结构
数据封装、解包和分用:
前面提到过:协议的其中一个本质就是一个结构体;两台计算机使用相同的网络协议就是使用相同的结构体。当然,网络数据结构体的内容是一步步添加的,这个过程和入栈惊人的相似!!!
先了解两个专业术语
- 有效载荷:就是用户眼里真正想要传输的数据,比如一个字符串
hello world!!! - 协议报头:就是网络协议每层眼里期望看到的属性,就像一个暗号(如两台计算机各自的网络层之间,或者两台计算机的数据链路层之间)
当用户试图通过网络发送数据
在应用层获得有效载荷(用户发送的数据),形成一个数据。
获得传输层层报头,堆在第 1 步组成数据的上方。
获得网络层报头,堆在1、2步组成的数据上方。
获得数据链路层报头,堆在1、2、3步组成的数据上方。
5.明晰一点:有效载荷和报头是软件层的概念,到了物理层后,软件层的生成的数据就该离开计算机进行传输了。
自此,一个结构体的至少4个成员就全部成功初始化了
当用户试图通过网络接受数据
其实顺序就正好相反,直接按照 数据链路层报头->网络层报头->传输层报头的顺序 就能一路解析到有效载荷,从而让上层用户得到从网络请求到的数据。
所以发送和接受数据不就是一个入栈和出栈的过程吗???
另外,这个入栈的过程就叫做封装;出栈的过程就叫做解包和分用(解包宏观上形容解析数据的过程,分用微观上描述每一个协议层都分别读取自己需要的部分)

报头的相关术语:
补充一些术语,让咱们更加专业!!!
- 应用层的有效载荷也就是数据
- 传输层的报头叫做数据段
- 网络层的报头叫做数据报
- 链路层的报头叫做数据帧
虽然又是段有时帧的,但本质上都是struct结构体!!!
混杂模式:
在解包和分用阶段,每一层默认只管术语自己的那一个报头。
但是,如果使用混杂模式,每一层就可以任意读取(向网卡发出请求)!!
就和前面提到的数据抓包是一个原理,毕竟说是分用,其实并没有真的把数据大卸八块,而是像快递送信一样集中配送,乖孩子自然就分用了,坏孩子就会偷偷把别人的信封也拆开看一遍。
跨网络传输(广域)
ip地址:
先有局域网,再有广域网。因此在广域网设计之初,世界各地就已经存在了五花八门的局域网实现方案。比如以太网通信中,两台主机通过
MAC地址来表示对方,但是使用无线LAN和令牌环网的主机就不认识MAC,这就是单一局域网的局限所在。
想要让全世界的主机都能够通过网络通信,就必须将唯一标识符统一,同时又不能抛弃原有的方案,也就是向前兼容。
俗话说,“在计算机的世界里,没有什么是加一层中间层不能解决的”。而这个中间层,就是现在广为使用的网络层里的
ip地址!!!
IP地址的版本
- IP地址分为两个版本,分别是
IPv4和IPv6。 - 其中,IP指的是网络协议(Internet Protocal), v指的是版本(version)。
- IPv4由四字节组成,IPv6由16字节组成;因此,后者是对于前者的补充(可以标识的主机更多!!!)
[!独当一面的IPv4]-
- 其实在IPv6出现之前,IPv4所能表示的主机数就已经不够了。
- 做一个计算,IPv4由4个字节,也就是32个比特位,可以表示2^32个主机,即42亿个,但是全球人口早就超过80亿了。更别说一个人可以有好多台不同的联网设备。
所以,除了IPv6外,还有一种解决方案,就是NAT——网络转换- 这个技术将IP分为了公网ip(全球唯一)和内网ip(只用保证局域范围内不重复即可)
- 当我们的主机访问公网时,路由器就会将我们的内网ip转化为公网ip,进而访问互联网。
#Linux/网络/独当一面的IPv4
跨网络传输过程:
上面解释过局域网之间数据传输的过程,跨网络的传输也是在此基础之上的。可以理解为跨网络传输就是由多个局域网之间的传输构成的。
如果要从福建到广东,不是一下子就到了(坐飞机除外)(福建)福州→莆田→泉州→厦门→漳州,入粤后经潮州→汕头→揭阳→汕尾,最终抵达广州(广东)因此,对于IP地址来说,关注的是福建和广州。
但是,对于局域网(如以太网)来说,关注的是途中一个又一个的市。
感性理解:在传输过程中,IP地址就代表了起始地址和最终的目标地址,而一个个局域网的地址就是从哪个市来,到哪个市去。
理性理解:主机A到主机C的网络传输
- 源数据包在主机A产生 :主机A应用层的数据自上而下进过协议栈后,形成了一个封装好的数据包。其中就包含了原MAC地址(主机A的)和目标MAC地址(主机B的),以及源IP地址和目标IP地址。
- 数据包传输到主机B时,进行解包和分用。而主机B的网络层发现,得到的IP地址和自己的IP地址不同,说明这不属于自己。于是再一次进行数据封装,大部分数据不变,将原MAC地址转换为自己的MAC地址,将目标地址转换为下一台主机(主机C)的MAC地址。源IP地址和目标IP地址不变
- 数据包传输到主机C时,同样是解包和分用。但主机C的网络层发现,分发到的IP地址和自己的IP地址相同,直接交给传输层,继而让应用层的用户拿到。
IP的核心作用:屏蔽底层
有了网络层IP的存在,屏蔽了底层物理网络的实现差异,让上层对于网络的使用变得更加方便。
MAC地址依然存在的意义:
既然IP地址能够标识的唯一主机数那么多,为啥MAC地址这些旧时代的产物依旧广为使用呢?
原因有二:
-
历史原因:要知道MAC地址更早出现,已经刻在不知道多少电脑的网卡里了,全部换成IP所带来的适配成本过高。“历史的车轮碾过,痕迹无法被轻易抹去”
-
解耦合:网络层就是为了对种类繁多的数据链路层进行大一统才产生的,如果强行将二者合并,则世界上所有的网卡驱动都要改写。(网络层属于软件层面的设计)
