目录
[🐼网络协议TCP/IP VS OS之间的关系](#🐼网络协议TCP/IP VS OS之间的关系)
🐼为什么要有网络
刚开始,计算机之间都是独立的,你开发你的,我开发我的,但是如果想互传时,就得拿着重重的盘去拷贝,这就会导致,在数据共享时极其不方便,会导致等待的过程。而如果我们能直接发送我开发的数据给你,你接受直接继续开发,双方的开发效率都会提高。没有网络如图:

网络互联: 多台计算机连接在一起, 完成数据共享;
假设我们在一个宿舍,我们直接可以直接通过主线连接起来,一起玩游戏。这解决了我们这个宿舍(小子网)的网络传输。如图:

可是,如果我们想和别的宿舍的玩游戏,难道我们把别的宿舍也接到我们这根网线上呢?有点麻烦了!于是当计算机数量更多了, 通过交换机和路由器连接在一起,构成一个局域网(LAN),如图:

可是我们还不甘心,还想和远在别的省的同学一起玩游戏,将远隔千里的计算机都连在一起;构成一个广域网(WAN)。
所谓 "局域网" 和 "广域网" 只是一个相对的概念. 比如, 我们有 "天朝特色" 的广域网, 也可以看做一个比较大的局域网.
总结一下,为什么要有网络呢?
因为计算机是人的工具, 人要协同工作, 注定了网络的产生是必然的,为了解决长距离的通信,就有了网络这种解决方案
🐼协议
✅什么是协议?
"协议"其实是一种约定,举个例子:
比如,你从南方到北方上大学,为了帮家里节省话费,就和家人做了一个简单的约定:电话响一声,是报平安;响两声,是提醒打生活费;响三声,就是有重要事情得当面聊。
这种基于事先约定好的信号来传递信息、达成一致的方式,其实就是"协议"最生活化的体现
✅协议分层
什么是协议分层呢?举个例子。我们打电话,好像是人和人直接在通信,但是其实会经历这么多层:
✅为什么要这么做,这么做的好处是什么?
因为不同性质,不同种类的问题,要有不同的解决办法,就像上面打电话一样。协议本质也是软件, 在设计上为了更好的进行模块化, 解耦合, 也是被设计成为层状结构的。
而好处就是某一层的协议出现了问题或者设备发生了更换,那么只需要处理那一层就可以了! !
这就和我们写代码的思想是一致的,因为协议本质上也是程序员相互协同好的。当一层出现问题不会影响另一层, 这就是低耦合;在写代码时,把某个功能的代码都集中放在一起,就是高内聚,也就是同一层协议的代码要内聚度很高!不同层协议的代码互不受影响
✅谁来定协议
如何让这些不同厂商之间生产的计算机能够相互顺畅的通信? 就需要有人站出来, 约定一个共同的标准, 大家都来遵守, 这就是 网络协议;
一般具有定制协议或者标准的资格的组织或者公司都必须是业界公认或者具有江湖地位的组织或者公司,也就是有话语权的。但是我凭什么听你的啊?你定的协议你让我干嘛我干嘛?因为我足够落后,如果我不紧跟他,不遵循他定的协议,其他人遵循他定的协议,那么我不就更落后了,即使我自已定协议,但是我协议定的不好,没有话语权,别人不用我定的协议,因为没人用我自已定的协议。所以,我是不得不听他定的协议,因为落后就要挨打。
🐼OSI七层模型
OSI(Open System Interconnection, 开放系统互连) 七层网络模型称为开放式系统互联参考模型, 是一个逻辑上的定义和规范;
把网络从逻辑上分为了 7 层. 每一层都有相关、 相对应的物理设备, 比如路由器, 交换机;
**它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整. 通过七 个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯;我们后面通过代码就能感受到OSI把协议定的特别好!**OSI七层协议如图:


🐼TCP/IP协议
其实在网络角度, OSI 定的协议 7 层模型其实非常完善, 但是在实际操作的过程中, 会话层、 表示层是不可能接入到操作系统中的, 所以在工程实践中, 最终落地的是 5 层协议。 如图:

一般而言
(1)对于一台主机, 它的操作系统内核实现了从传输层到物理层的内容;
(2)对于一台路由器, 它实现了从网络层到物理层;
(3)对于一台交换机, 它实现了从数据链路层到物理层;
(4)对于集线器, 它只实现了物理层;
但是并不绝对. 很多交换机也实现了网络层的转发; 很多路由器也实现了部分传输层的内容(比如端口转发);
🐼网络协议TCP/IP VS OS之间的关系
OSI定了标准,但是他不落地标准,谁来落地呢?各个OS系统的程序员。如图是windows和Linux对于网络协议的对比。我们发现os系统不同,但是协议必须相同,网络协议栈必须相同,这样不同的系统之家,就可以互相通信了!这就是互联网的基础。OS系统分家,但是协议不分家!

暂时。为什么长这样。
🐼再来谈谈什么是协议?
协议本质上就是一个约定,通过不同的字段来描述程序员之间定的协议,所以协议本质是一个结构体。Windows和Linux尽管OS系统不同,但是OSI建立了共识,协议必须相同。而如何做到协议是约定呢?
OS 源代码一般都是用 C/C++语言写的

问题是,主机 B 能识别 data, 并且准确提取 a=10, b=20, c=30 吗?
答案是肯定的!因为双方都有同样的结构体类型 struct protocol。 也就是说,用同样的代码实现协议, 用同样的自定义数据类型, 天然就具有"共识", 能够识别对方发来的数据, 这不就是约定吗?不就完成了跨平台性吗?
关于协议的朴素理解: 所谓协议, 就是通信双方都认识的结构化的数据类型因为协议栈是分层的, 所以, 每层都有双方都有协议, 同层之间, 互相可以认识对方的协议。
我们左手有了协议,右手有了协议要分层的概念。而其中每层都有协议, 所以当我进行进行上述传输流程的时候, 要进行封装和解包。而协议本质上就是结构体。所以如果主机A给主机B发送数据,每一层都会有协议,也就会多一些字段,而根据OS系统的层状结构,TCP/IP协议和OS系统的关系,数据一定会贯穿整个协议栈!如图:

下面我们明确一下概念

报头部分, 就是对应协议层的结构体字段, 我们一般叫做报头
除了报头, 剩下的叫做有效载荷故,
报文 = 报头 + 有效载荷
不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报 (datagram),在链路层叫做帧(frame).
应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation).首部信息中包含了一些类似于首部有多长, 载荷(payload)有多长, 上层协议是什么等信息.数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,根据首部中的 "上层协议字段" 将数据交给对应的上层协议处理
🐼为什么叫做TCP/IP协议栈
在网络传输的过程中, 数据不是直接发送给对方主机的, 而是先要自定向下将数据交付给下层协议, 先进行数据封装,这是入栈过程。如图:

最后由底层发送, 然后由对方主机的底层来进行接受, 在自底向上进行向上交付,对数据进行解包,完成分用,这是出栈过程。
那么解包、分用又是具体如何做到的呢??
任何协议,应用层外,都要解决两个问题:
1. 都要提供一种能力,将报头和有效载荷分离的能力(解包)
2. 几乎任何层的协议, 都要在报头中提供,决定将自己的有效载荷交付给上层哪一个协议的能力(分用)
如果我们换个视角,从原本的垂直视角过渡为水平视角,那么同层之间,压根不需要考虑下面是如何做的,它们认为自已直接在于对方通信。

分用的过程如图:

现在,我们要建立宏观认知,如何进行解包,如何分离有效载荷,分用交给上层协议。一定要有这样的思考!
🐼局域网通信原理
首先回答, 两台主机在同一个局域网, 是否能够直接通信? 是的
以太网是如何通信的呢?原理是什么?举个例子:
老师在课堂上喊了一声"张三,请站起来"。全班同学都听到了这句话,但只有张三站了起来。其他人虽然也接收到了信息,但在"识别"之后发现不是叫自己,就自动忽略了。
这就像网络通信中,数据包虽然可能被多个设备接收到,但只有目标主机会处理它,其他设备会丢弃不属于自己的数据。
在局域网内发送数据,所有主机,怎么知道发送数据是不是发给自已的?是如何知道的?
每台主机在局域网上, 要有唯一的标识来保证主机的唯一性: mac 地址
什么是mac地址呢?
MAC 地址用来识别数据链路层中相连的节点;也就是同一个局域网(子网内)
Mac地址长度为 48 位, 及 6 个字节. 一般用 16 进制数字加上冒号的形式来表示。在网卡出厂时就确定了, 不能修改. mac 地址通常是唯一的(虚拟机中的 mac 地址不是真实的 mac 地址, 可能会冲突; 也有些网卡支持用户配置 mac 地址).我们可以使用ifconfig来查看相关信息,比如IP和MAC地址
以太网中, 任何时刻, 只允许一台机器向网络中发送数据(这不就相当于我们系统中的锁功能吗),以太网不就是共享资源,临界资源。需要被保护起来吗?我们站在系统角度很好理解
如果有多台同时发送, 会发生数据干扰, 我们称之为数据碰撞
所有发送数据的主机要进行碰撞检测和碰撞避免
没有交换机的情况下, 一个以太网就是一个碰撞域
局域网通信的过程中, 主机对收到的报文确认是否是发给自己的, 是通过目标mac 地址判定
既然以太网是临界资源,那么如果我能无限制的发送数据到局域网,那么我就可以黑掉这个网络了!
如图所示:

明白了局域网通信原理, 再来看同一个网段内的两台主机进行发送消息的过程,如图:

而我们既然已经知道了什么是协议栈,如果我们换个视角,与其说局域网内的主机通信,不如说是局域网内的网络协议栈在通信!

需要注意的是,是不是局域网越大碰撞概率就越大,如果一太主机发送的报文越长,碰撞概率越大,所以一般不建议太大,否则会影响传输效率,所以就需要用交换机来划分碰撞域!!如何隔离的,为什么能隔离?这点我们后面再聊。
🐼跨网络传输
我们已经知道局域网内通信主要靠MAC地址,MAC地址可以保证局域网中主机的唯一性。
但是如何跨网段实现主机间数据传输. 比如从一个局域网到另一个局域网呢?这就需要IP地址。
IP地址保证主机全网的唯一性
✅什么是IP地址?
IP 地址是在 IP 协议中, 用来标识网络中不同主机的地址 ;
对于 IPv4 来说, IP 地址是一个 4 字节, 32 位的整数
我们通常也使用 "点分十进制" 的字符串表示 IP 地址, 例如 192.168.0.1 ; 用点分割的每一个数字表示一个字节, 范围是 0 - 255;
正是因为IPv4的数量不足,也就2^32个IP地址,远远满足不了现在的需求了,才有了ipv6,长度128位.但是这也不是唯一解决方案,因为有了子网划分技术。这也就是为什么我国ipv6推广难得原因。
数据从一台计算机到另一台计算机传输过程中要经过一个或多个路由器,就叫做跨网络传输。
✅如何理解跨网络传输呢?举个例子:
想象唐僧要去西天(目标IP地址)取经。到了长安城门口(第一个路由器) :唐僧问卫兵:"西天怎么走?"卫兵查看路标(路由表),告诉他:"下一站,五行山。"到了五行山(下一个路由器) :唐僧又问土地公:"西天怎么走?"土地公查了查路标,告诉他:"下一站,高老庄。"就这样,每到一个"站点"(路由器),当地人都会根据最终目的地(西天),告诉他下一个最近(最佳)的"站点"(下一跳)该去哪。
最终,唐僧经过一站站的指引(路由转发),最终成功抵达西天(目标主机)
在这个过程中,唐僧从哪里来,到哪里去始终没变,也就是源IP,目的IP始终不变。而唐僧上一站从哪里来,下一站去往哪里始终在变。也就是上一个MAC地址和下一个MAC地址。MAC地址会根据目的IP地址,动态选择出所经历的MAC地址(就是哪些主机/路由器)。这个过程就好像人根据目标确定路径是一个道理。就是根据目的IP不断淘汰一些道路,动态选择最佳路线的过程,这个过程可能会经历不同的困难和挑战。
✅如何具备路由的条件?只要主机有网络层即可
但是,我怎么知道我的报文是发给在局域网内,还是发给跨网络的另一台主机的呢?谁决定的?IP地址。如果IP地址属于同一个网段,即该报文是发给局域网内的,只需要知道目的主机MAC地址即可。但是如果IP地址和自已不属于同一个网段,那么就要推给路由器,也就是该问路啦~让路由器告诉我们往哪走,离我们的目的主机能更近一步~ 如图:

✅对比 IP 地址和 Mac 地址的区别
IP 地址在整个路由过程中, 一直不变(目前只能这么说,后面其实IP地址随着NAT转换也是在变的)
Mac 地址一直在变,并且只在局域网内有效
目的 IP 是一种长远目标, Mac 是下一阶段目标, 目的 IP 是路径选择的重要依据, mac 地址是局域网转发的重要依据如图:

🚩如果我们把视角聚焦在数据链路层,我们会发现,MAC地址一直随着每经历一个路由器就会变化,所以数据链路层的报文是一直在变化的。
🚩我们把视角聚焦在网络层,我们会发现,IP地址永远不变,也就是在网络层,大家看到的报文都是一样的。我们的互联网是建立在网络层基础上的,IP地址,虚拟化了底层互联网的差异!这也就是为什么底层数据链路层有那么多实现方案,比如以太网,令牌环网,无线局域网,ppp协议等等。因为站在在网络层,这些技术已经毫无关系了。这也就是为什么协议要分层的原因,进行解耦,甚至可以直接替换底层技术,对于上层都是透明的~
所以IP 网络层存在的意义: 提供网络虚拟层, 让世界的所有网络都是 IP 网络, 屏蔽最底层网络的差异。 如图:
