网络基础(一)

计算机网络背景 

网络发展

网络在哪里 

认识协议

什么是协议 

"协议" 是一种约定

只要通信的两台主机, 约定好协议就可以了么?

如何让这些不同厂商之间生产的计算机能够相互顺畅的通信?

网络协议初识

协议分层

打电话例子

协议为什么要分层(分层在软件结构的好处)?

协议具体是怎么分层的呢?

OSI七层模型

OSI七层模型图 

TCP/IP五层(或四层)模型 

网络传输基本流程

理解四层协议的作用

TCP/IP的通讯过程

局域网中的两台主机能直接通信吗?

什么是报头呢?

如何理解报头?什么是报头?为什么要有报头?

在计算机OS中,如何理解报头和数据(有效载荷)呢?

Linux是C语言写的,站在语言角度,如何理解封装和解包呢?

什么叫封装呢?

什么叫做解包?

当报文在解包的时候,传输层这里除了TCP协议还可能还有个UDP协议,那么ip向上交互的时候到底是交给TCP还是UDP呢?

数据封装的过程 

数据分用的过程

局域网通信原理 

局域网是怎么把数据转给下一个主机或者路由器的?

同一个局域网之间的主机能通信吗?为什么?

以太网通信原理

网络中的互斥 

如果我想攻击这个局域网,我该怎么做?

局域网通信过程中数据会泄露吗?

令牌环的局域网通信原理

网络中的地址管理

​编辑

Mac地址

关于ip和mac地址

唐僧身上是可以有几套地址的呢?

所以我们在正常情况下,进行正常路由的时候,一般目的ip是不变的,目的mac是一直在变的,为什么mac在变呢?

ip的意义 

先有计算机还是先有操作系统呢?

先有计算机,才有的OS。

先有OS,还是先有的网络呢?

先有OS,才有的网络。

先进设备会流入高校,高校内部有数据研究的需求和沟通的需求,产生网络,最终的目的是提高效率.

计算机网络背景 

网络发展

独立模式 : 计算机之间相互独立 ;

网络互联: 多台计算机连接在一起, 完成数据共享;

局域网LAN: 计算机数量更多了, 通过交换机和路由器连接在一起。

交换机是工作在数据应用层的一个设备。左侧是一个局域网,右侧也是一个局域网,这些局域网之间,彼此在各自的网络内部是可以直接通信的。但是它俩是两个独立的模块,所以最终就需要一个设备路由器,它能实现跨网络转发。随着网络的发展就由一种简陋的多主机直连的方式,我们就构建了局域网,局域网与局域网之间我们就可以使用路由器来链接。我们一般把局域网叫做局域网LAN,有了局域网之后,多个局域网可以通过路由器来连接起来,实现数据的跨网络传送。

所以,家里想上网的时候,有两个设备是必须有的,一个是路由器,另外一个是强制解调器(俗称猫,它是一个物理层的设备,主要是将物理信号和光电信号进行转换)。我们知道,只要我想上网就必须得有路由器。你家里本来就是一个局域网。

广域网WAN: 将远隔千里的计算机都连在一起;

所谓 "局域网" "广域网" 只是一个相对的概念. 比如, 我们有 "天朝特色" 的广域网, 也可以看做一个比较大的局域网.我们中国就访问不了谷歌,推特,Facebook,这是因为有墙的存在,一旦我们有这个需求,就会被中间运营商给阻止了。

网络在哪里 

linux下一切皆文件!

每一个文件的结构体内包含一组函数指针,函数指针指向底层的方法,不同的硬件函数指针指向不同的方法,此时就可以用同一个struct file指向不同的底层的设备访问方式来实现一切皆文件。

eg:一切皆文件,我们封装了一个文件的虚拟层,再加底层对应的具体硬件,对应底层的驱动程序,不同硬件的操作方法。

软件也是可以分层的!

我们写C++代码,经常会使用STL接口,我们一般是没有关心过STL底层库的实现原理的。STL库叫做一层软件层,上面做应用开发叫做另外一层。所以软件是可以分层的。   

eg:STL程序分两层,上层是我自己调用stl实现的功能,下次就是STL库的对应的内容,STL库底层还有其他的第三方库,包括系统调用也是可以分割成软件层的。    

我们常见的网络协议是份四层的,这里指的是软件层。当然如果你在想去做划分的话,还有一层物理层,也是很多教材喜欢按照5层协议的原因。博主在这里按自顶向下4层来讨论。

我们发现网络协议栈是贯穿体系结构的,尤其是传输层和网络层,这两层是OS内核的一部分。传输层和网络层最经典的协议是TCP和IP协议,所以我们把这样的协议栈,称之为TCP/IP协议栈。当然,在我们看来,应用层和传输层是最重要的。

这里的网络,指的是网络协议栈,它是一个软件,贯穿体系结构的,TCP/IP是属于OS的一部分。

认识协议

协议是协议栈中一个关键的概念,协议和协议栈的区别,就和电话和打电话的区别一样:

协议栈就是今天这层软件层相当于电话;

协议,我们将来用计算机语言表述好协议之后,就相当于用协议进行通信了,所以要打电话。

什么是协议 

"协议" 是一种约定

比如:电话在刚刚兴起的时候,电话费是非常非常贵的,其中父子两个人因为电话费的问题形成了两个约定,比如你和你爸说,我去学校了,肯定得常联系,但是电话费太贵了,你就和你爸做了一个约定,如果

1.我给家里打电话,电话响一声,我就挂掉,代表我是平安的。

2.我给家里打电话,电话响两声,我就挂掉,代表我没钱了。

3.我给家里打电话,电话响三声,我有其他事情要沟通,你就接电话。

所以有一天,你爸在电话旁,看见来电是你,响了一声,你爸就知道,你是报平安的。过来两天,你爸发现又来个你的电话,这次响了两声,你爸就意识到你没钱了,然后就给你打钱。当你的电话响了三声,你爸就知道你想和他聊天了。

我们把这种人级别的约定,用计算机语言,这个约定就被称之为协议。所谓的计算机协议本质就是约定,约定是由编码的程序员自己根据标准文档,或者自己的喜好定义的协议!

比如今天机器A和机器B进行协商,A给B发一个X数据,B就执行一下1+1,A给B发Y字符的时候,B就算一下10*10,总之A给B发不同的字符,B就做不同的计算。这就叫做协议。两台计算机上的协议是由程序员定的,程序员可以通过确定发送一些特定的字段来保证对方执行特定的行为,甚至响应特定的报文。这就叫做协议。

计算机之间的传输媒介是光信号和电信号 . 通过 " 频率 " " 强弱 " 来表示 0 1 这样的信息 . 要想传递各种不同的信息, 就需要约定好双方的数据格式 .

只要通信的两台主机, 约定好协议就可以了么?

假如就是两台计算机通信,A计算机认为0,1是强弱,B认为0,1是有无,A,B都遵守了协议,用不同的信息方式表达不同的含义。我们都采用0,1通信,但是具体实现有差别的话我俩是没办法通信的。
现实生活中,人类的语言是充满协议的。比如你回家和你爸你妈说,我饿了,你爸妈就会根据历史上几千年的约定,当你饿了,就给你做饭,让你吃。但是当你回去和你爸妈说,I am hungry.首先你是遵守了协议的,但是你爸妈可能没学过英语,不知道你在说些什么,此时你也遵守了协议给对方说我饿了,但是对方无应答。因为光考虑一些约定是不够的。因为我们世界的 计算机生产厂商有很多; 计算机操作系统 , 也有很多 ; 计算机网络硬件设备 , 还是有很多;我们每个人遵守你的协议,但是实现细节上如果不一样,美国人表达饿了就是hungry,中国人就是我饿了。两者都遵守了几千年表达饿了的协议需求,对方听懂了一定会给我们执行的,但是如果交叉了,就没法互相通信了。所以协议即便定义好了,但是实现细节上有如果差别的话,我们也没办法通信。

如何让这些不同厂商之间生产的计算机能够相互顺畅的通信?

这时候就需要有人站出来 , 约定一个共同的标准 , 大家都来遵守 , 这就是 网络协议 ;就好比全世界的人通信的时候,你说你的,我说我的,我们都能用自己的语言,完成生活中定义好的各种协议动作,但这只适合与本国人交流,一与外国人交流,对方就听不懂。所以就有了国际通用语言,大家统一用英语,用英语的时候遵守同样的协议以及同样的实现方式完成协议,我们就能让多台主机互相通信了。
计算机中的协议是一样的,同时我们需要有组织帮我们共同定制网络通信协议,也就是从协议的定制到实现我们全都是标准化的东西,不允许存在个性化的东西。然后就可以实现多主机通信了。这也就是为什么小米的笔记本,华为的笔记本,苹果的笔记本等都可以和你的设备直接互连,原因就是大家采用的是同样的标准规定。
网络协议组织是由对应的OSI组织统一定的,真正能站出来定制协议的人,一定是这个行业的龙头老大。典型的就是华为定制5G标准,这也是通信协议。

网络协议初识

协议分层

打电话例子

我们在现实生活中也是一种层状结构,你和你的朋友用同一种语言互相进行通信,不管底层是什么样的通信设备,最终只要转化回去就可以。我们与电话就是一种层状结构,就是一个两层协议。

协议为什么要分层(分层在软件结构的好处)?

通过分层完成了解耦,一旦解耦后,任何一层你想要进行替换,那么你就可以直接进行替换,而并不会影响另外一层,即便是一层当中有bug,你只需要将问题聚焦在这一层即可,而不影响其它层,这就是软件分层的诸多好处。

协议具体是怎么分层的呢?

不同的软件实现的差别是非常大的。首先,协议是将来软件的一种,协议分层,本质上也是软件分层的一种,软件无非就是代码和数据,代码在C语言层面上就是各种函数,在C++上就是各种计算逻辑,数据在C语言层面上就是各种变量和结构,以及各种结构构建好的数据结构,在C++上就是各种对象。既然叫做软件分层,那么一定就是在代码层面上进行的逻辑分层,以及在数据层面进行分层,当然层和层之间一定会有交互,所以代码一旦分层,在数据层面上,让数据在不同的层之间进行流动。

具体的例子:就像一切皆文件,因为linux内核是用C语言写的,它要管理任何对象的时候肯定是先描述再组织,文件系统也同样如此,所有的东西都被当做文件对待了,文件中公共的属性,公共的方法就是读写,我又得把所有的东西统一到文件里来看,所以我需要抽象出一种文件结构,这个文件结构的属性就是文件的属性,方法里面包含一堆的函数指针,这个函数指针指向的是具体的访问不同的底层设备的方法,完全取决于你的底层设备是什么样子,上层就可以统一用同样的方式看待文件,这种就叫做一切皆文件的底层实现,就相当于结构体套函数指针。它其实就是一种在逻辑上划分好的软件层状结构。

OSI七层模型

网络协议栈是种层状结构,业界老大规定这种层状结构。我们用来定义协议的组织就叫做OSI,它规定了一种7层网络模型

  • OSIOpen System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型, 是一个逻辑上的定义和规范;

在计算机里面,所谓的逻辑上就是没有真实存在,而是用某种代码或者某种抽象的方式模拟出来的,就叫做逻辑上的。曾经进程的虚拟地址空间就是逻辑上的定义和规范,进程地址空间是描述一个进程所能看到的空间范围,站在进程的角度就认为自己有多大的空间,而这个空间是OS模拟出来的。在直白一点,逻辑上就是硬件上不实现,由软件帮你实现,软件帮你实现的具体方法就是增加一些软件层来帮助我们实现逻辑上的定义和规范,就好比我们在学习进程地址空间的时候,mm_struct就是一种软件层,我们在学习一切皆文件,我们在逻辑上封装了一个虚拟文件系统,就叫做进程所对应的struct file,打开文件之后,struct file结构体里面有一批操作指定具体文件类型的方法,它对应的函数指针,实际上也是软件上的一种设计方案。

  • 把网络从逻辑上分为了7. 每一层都有相关、相对应的物理设备,比如路由器,交换机;(但也不一定,理论上是有的)
  • OSI 七层模型是一种框架性的设计方法,相当于是一套规范,这个规范虽然定出来了,但是在实现编码的时候,可能会有一些变化,所以也就是只用了一部分,很多内容也没完全实现(处于一种概念的阶段)。在应用领域,我们就按照一些实际情况,设计出4层或者5层协议(这个5层或者7层是包括了物理层的,实际上我们要讨论网络协议栈它是纯软件的,不应该谈物理层,但是像网络这种,如果撇开物理层不谈,是很难说清楚的)。OSI七层模型其最主要的功能使就是帮助不同类型的主机实现数据传输;
  • 它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整. 通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯;
  • 但是, 它既复杂又不实用; 所以我们按照TCP/IP四层模型来讲解。

OSI七层模型图 

TCP/IP五层(或四层)模型 

这是我们在现实中所用的,是在工程实践当中真正做出来的,我们以此介绍层状结构。

TCP/IP叫做软件协议,不包括硬件,所以说五层的都是不准确的。

TCP/IP 是一组协议的代名词,它还包括许多协议,组成了 TCP/IP 协议簇 .
TCP/IP 通讯协议采用了 5 层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求 .
  • 物理层: 负责光/电信号的传递方式. 比如现在以太网通用的网线(双绞线--带水晶头的网线)、早期以太网采用的的同轴电缆 (现在主要用于有线电视)、光纤, 现在的wififi无线网使用电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等. 集线器(Hub)工作在物理层.

比如:打游戏,英雄任务释放的技能不管有多么酷炫,但是在计算机底层就是一堆二进制数据,要么传输,要么计算,要么展示。在硬件层面压根就不知道0,1序是什么意思,我只需要你告诉我,我需要传多少光电信号,这就是物理层解决的问题。物理层更多的是你只需要告诉我你要传光电信号,第一传多少,第二什么时候传,我只需要帮你做就可以了。

光电信号都是有自己的初始波段和能量的,它的传输距离是有限的,当他传输上一段距离之后,信息传输在物理上都是有衰减的,信号衰减了,我们可以把信号衰减在给他放大,这就叫做集线器,就好比这个信号不行了,我就把他放大一下,放大之后它可以传播的更远。

物理层是我们的硬件,但是硬件是不能由对应的OS直接去访问的或者操作的,所有的硬件都有它的驱动程序,数据链路层就是特定的硬件所匹配的一种驱动模块。 

  • 数据链路层: 负责设备之间的数据帧的传送和识别. 例如网卡设备的驱动、帧同步(就是说从网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、数据差错校验等工作. 有以太网、令牌环网, 无线LAN等标准. 交换机(Switch)工作在数据链路层.
  • 网络层: 负责地址管理和路由选择. 例如在IP协议中, 通过IP地址来标识一台主机, 并通过路由表的方式规划出两台主机之间的数据传输的线路(路由). 路由器(Router)工作在网路层.
  • 传输层: 负责两台主机之间的数据传输. 如传输控制协议 (TCP), 能够确保数据可靠的从源主机发送到目标主机.
  • 应用层: 负责应用程序间沟通,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等. 我们的网络编程主要就是针对应用层.

物理层我们考虑的比较少. 因此很多时候也可以称为 TCP/IP四层模型.
一般而言
  • 对于一台主机, 它的操作系统内核实现了从传输层到物理层的内容;
  • 对于一台路由器, 它实现了从网络层到物理层;
  • 对于一台交换机, 它实现了从数据链路层到物理层;
  • 对于集线器, 它只实现了物理层;
但是并不绝对 . 很多交换机也实现了网络层的转发 ; 很多路由器也实现了部分传输层的内容 ( 比如端口转发 );
越靠近上层的硬件设备,实现的协议的层级越高。

网络传输基本流程

理解四层协议的作用

我们通过生活中引入:我们是买过快递的,你今天是一个客户,你在江浙沪地区买了一个洗面奶,产品描述是可以祛痘,符合你的需求,你就买了一个。卖家此时就要把你买的洗面奶通过快递的路径交互到你的手上,卖家第一件事情就是把洗面奶给你打包成快递,打包成快递的时候就要先找一家快递公司,找快递公司的时候,卖家先下楼,下楼之后把洗面奶拿盒子装起来,这个行为我们在网络里面就称之为封装。卖家还需要填一个快递单,填写好客户的资料,然后这个快递就需要被派送了。卖家把这个快递交给顺丰,然后卖家此时就不管了,我反正把快递发出去了,后面这个快递能不能被收到不是我的事情,而是顺丰的事情。然后顺丰就给你选择邮寄路径,浙江-山东-福建-云南-陕西-甘肃,所以开始给你派发的时候,把快递送给下一站是由数据链路层决定的(通过空运,还是海运,还是陆运...)。顺丰做路径选择的时候,这是由网络层决定的。比如:你出去旅游,你首先会做旅游攻略,第一站去哪,第二站去哪...,你在做攻略的时候,你自己所处的角色就叫做网络层,叫做路径规划。再比如:我们在山东,下一站去福建 ,但我们还没走,只是计划好了,具体走的过程就由数据链路层决定。回到快递的例子,卖家把快递交给顺丰,顺丰做路径选择,然后进行派发快递,这都没问题,但是如果快递丢了呢?传输层解决这个问题,一旦快递丢了,我就给你赔钱或者重给你发一份。就好比客户收到洗面奶发现洗面奶被压坏了,就和卖家反应,卖家就重发一个,这时候卖家做的工作就类似于传输层做的工作,叫做保证可靠性,更准确的讲就叫做传输控制。

在网络通信里存在一个误区:认为数据传输给对面,事情就完了!数据传输给对面这个只是第一步,最重要的是如何分析和使用传输过来的数据。 就好比:你拿到你的洗面奶,肯定不是顺手把他丢进垃圾桶(因为传输任务已经完了),我们把数据拿到后,只是完成了第一件事情,第二件事情就是我们要使用它,这就是应用层要解决的问题。
所以下三层解决的是如何让你拿到的问题,应用层解决的是这个拿到的数据我们该如何分析和使用。    

TCP/IP的通讯过程

TCP/IP协议是在内核当中的,数据链路层严格意义上来讲不属于OS,属于网卡驱动程序那部分,应用层在OS之上,下面那三层在OS之下主要处理通信细节,上层的应用层是用户进程主要处理应用程序细节。

你买完快递之后,这个盒子的颜色是灰色的,白色的,红色的你关心吗?快递是如何包装的...这些你压根就不关心,这叫做你的快递被派发时的派发细节。下三层处理的是通信细节,但是用户压根就不关心,用户只要知道你能就行了。这些通信细节都是内核去完成即OS去完成,应用层主要用来处理应用程序的细节。比如:你收到包裹后,你是用小刀割开,还是用其他利器割开,割开之后你的盒子扔到了哪里,里面的洗面奶是如何用的,一次用多少....你在使用过程中的细节,给你派发快递的小哥压根是不关心给你派发的是什么东西,你也压根不关心快递小哥怎么给你派发的这个东西。这就叫做应用层处理应用程序的细节。我们的世界本来就是应该有解耦的。

局域网通信过程中,下三层重点解决的是通信细节,应用层解决的是应用程序相关的应用细节。

局域网中的两台主机能直接通信吗?

答案是可以的。

eg1:家里的网络经常是这种状态

比如你欠费了就告诉你此时你家里的路由器连外网是断开的,就是没有外网,但是你的电脑和你家的WiFi是连接成功的。

你的电脑和你家WiFi,是你的电脑和你的路由器设备,我们可以把你的电脑和路由器看做是两台主机,当你家不能上网的时候,但是这两个属于同一个网段,所以他们两个其实是可以通信的。

eg2:比如cs,学校断网,但是某个楼层是在一个局域网内的,打开cs客户端,你在局域网创建一个房间,即便没有网,大家也是可以联机玩的。

实际上数据在通信的时候是分层的,每一层是什么意思,每一层的核心协议是什么以及数据在进行转发交互的时候以何种方式进行.....

实际上数据在进行局域网转发的时候是能够直接通信的,比如上层发送了一个你好这样的信息,你好这个信息在发送的时候,不是直接从你的应用层到了对方的应用层,它必须贯穿协议栈走最低下的以太网,到以太网中然后向上再走,必须是这样的一个工作方式。

这就好像:我是你们学校的老师,我在A教学楼的4楼,对面是B教学楼,我们两个楼在一个区域,比如我是一个辅导员,你是一个班长,我和你说,你把这个文件送给对吗B楼401的老师,此时要你转发报文,你不能直接从这个4楼直接飞到对面的四楼,你必须先从A楼下到1层,然后走到对面楼下,然后在上楼,找到对应的401,把文件送给401的老师。所以最底下的一定是物理层,人不能直接楼层飞过去到对方,所以不论是局域网还是广域网我们的数据报文,我们一定要自顶向下贯穿协议栈层,当收到之后对方也一定能够自底向上再贯穿它的协议栈。

协议栈软件是分层的,将来多台主机不管是局域网还是广域网通信的时候,一定是先自顶向下走到最底层的协议,然后脚踏实地般的在物理层上被传输,不能直接“飞过去”,到了对端主机后,在自底向上进行交互,这就是一个基本的流程。但是每一层协议在自顶向下交互的时候,比如你要发的数据是你好,每一次不是平白无故的进行交互的,而是要添加自己的报头信息 。

什么是报头呢?

就好比上层用户发了一个你好到应用层,应用层也要添加自己的报头,然后应用层将你好的数据+自己的报头整体打个包,然后再交互给下一层,传输层也要添加自己的报头,到网络层,网络层也添加自己的报头,到链路层,链路层也要转发和发送,所以它也添加自己的报头,最终数据就以这样的方式在网络里面跑,跑到对端主机对端以太网驱动,一端发什么,另一端就收什么,收到后就向上交互,每一层协议向上交互报文时,会去掉自己当前层的协议报头,然后交给上一层。

最终我们发现同等的层在逻辑上会得到同样的报头+报文,也就意味着在每一层看来,都认为我发什么,对方就应该收什么,这叫做同层协议,好像都认为自己在和对方直接通信。左侧不断给原始数据添加报头的过程称之为封装的过程,另一个自底向上把报文的报头的字段一个一个再解析出来,只保留它的有效部分,这个过程称之为解包

只要有网络,我们在逻辑上都认为自己在和对方直接通话,只不过在技术角度是要经过很多的报文的解包封装的。

如何理解报头?什么是报头?为什么要有报头?

还是发快递的例子,所有的快递盒子上面都有快递单,这个快递单就包括了收发件人的信息,快递单的格式和数据尤为重要,我买了一个洗面奶之后,实际上我只需要洗面奶对应的产品就可以了,但为什么我收快递的时候要贴这个快递单呢?这个单子就类似于快递的报头!!!如果快递没有快递单,我们就不知道这个快递是谁发的,也不知道发给谁,带来的后果就是无法得知该快递如何派发。快递单的意义就是指导我们进行派发。

存在报头就是因为需要报头中的数据,来指导当前层进行某种协议决策。因为我们的层比较多,所以传输层指导如何传输,网络层就指导如何进行路径选择,链路层的报头就指导我们如何进行下一跳转发,这就是报头存在的意义。

生活角度:当你收到一个快递单的时候,你根本不需要这个快递单,你收到快递把包裹一拆,然后把里面东西拿出来,盒子直接扔掉,盒子上贴的快递单的纸也就一并扔掉了,这就叫做解包的过程。而你给别人发快递的时候,只把东西给别人是不够的,你需要把东西给快递公司,然后填一个快递单,把你的东西装进盒子里,然后把快递单往盒子上一贴,这就叫做封包的过程。快递单是指导我们进行某种协议决策的,将来在特定的协议上,每一个它自己的报文都是有自己特殊的用途的。

在计算机OS中,如何理解报头和数据(有效载荷)呢?

在当前层中,它的报头就叫做报头,它的另一部分叫做这个报文的有效载荷

报头也是数据,它是一种结构化的数据。

Linux是C语言写的,站在语言角度,如何理解封装和解包呢?

网络里面,所有的报头其实就是一个位段类型。

什么叫封装呢?

最终用户有个数据,用户一定是在一个缓冲区里面。假设这个缓冲区里面有一个你这样的字段,然后我们要添加报头就是把变量的内容填充好之后,紧接着把变量拷贝进“你好”(有效载荷)的前面就可以了。在本质上讲一个报头就是把一个位段拷贝进一段缓冲区,然后再把你的有效载荷也拷贝进去。这个地方拷贝的时候我们可以采用memcpy或者memmove这样的二进制拷贝,我们就可以直接把一个变量拷贝进内容当中。我们还可以再添加其他报头,就是在定义其他的报头结构体,填充字段,把字段往前拷贝就可以了。

什么叫做解包?

解包:我可以定义一个指针指向报头的头部,比如说void* ptr,然后对这个ptr做一个强转,(struct my_hdr*)ptr,然后这个指针就可以访问这个报头里面的所有字段,访问完成之后,去掉报头就相当于 (struct my_hdr*)ptr++;对指针++,其实是+上其所指向类型的大小。这个ptr被强制成了结构体,位段类型,本来指向报头前边,一强制后做++,就直接指向末尾,相当于把这个报头个去掉了

当报文在解包的时候,传输层这里除了TCP协议还可能还有个UDP协议,那么ip向上交互的时候到底是交给TCP还是UDP呢?

对于封装,它要吧报文交给那个协议其实是可以指明的,从上向下比较简单,但是反过来其实是比较困难的,其中我们把一个报文交给上层哪个协议必须由当前层收到的报头去决定,所以几乎每一层协议的报头中,都要包含两种字段:

1.当前报文的有效载荷要交付给上层的哪一个协议!比如IP协议里面一定有一个字段,告知ip要将自己的报文交给TCP还是UDP,这个过程我们叫做分用的过程。也就是说当我们的每一层协议拿到了一个报文,实际上它要做两件事情,一个叫做解包,一个叫做分用。 第一个字段对应分用

2.几乎每个报头,都得明确报头和有效载荷的边界。你要进行解包,就有可能多解或者少解,多解或者少解都有可能导致有效载荷不完整,其中对每个报头就要明确一下哪部分是报头,哪部分是有效载荷,这个信息其实是在报头里面包含的,每个报头里面都会有一个字段用来标识它的有效载荷是多大。第二个字段对应解包。

这两种字段是所有协议的共性。

所有的报文(报头+有效载荷),报头里面一定能帮助我们做两件事情,第一件就是将报头和有效载荷进行分离;第二件事情是决定我的有效载荷交付给上层的谁,这就叫做解包和分用。 

数据封装的过程 

数据分用的过程

局域网通信原理 

我们以下面的例子展开论述: 

跨网段的主机的文件传输. 数据从一台计算机到另一台计算机传输过程中要经过一个或多个路由器 

A主机和B主机不在同一网段,他俩不属于同一局域网,因为他们经过路由器连接了,主机A和路由器,主机B和路由器,彼此之间是在同一个网段的。 就好比现实中,有两个人天生不和,想要解决这两个人的矛盾就需要有一个中间人帮助进行调解,虽然A,B不见面但是A可以把信息传递给中间人,进而传递给B。B亦是如此。这个中间人的角色就像这里的路由器。换句话说,A必须能和路由器直接沟通,路由器能直接和B进行沟通,利用路由器就可以做到A和B进行沟通。我们由上图可以看出A主机和路由器是以太网进行通信,B主机和路由器是令牌环通信。以太网和令牌环都是局域网。

局域网是怎么把数据转给下一个主机或者路由器的?

每个主机都连上了同样的网线,假设B主机和G主机要进行通信,B主机就把自己的数据放在局域网中,G主机收到之后就拿走。

同一个局域网之间的主机能通信吗?为什么?

答:能。局域网通信的原理就类似于上课。

假设我们在一间大教室里面上课,当老师喊了声,张三,请站起来,说一下为什么你的作业没有完成,这就话在教室的所有人都听到了,但是最终只有张三一个人站起来了。

第一个问题:为什么张三站起来了? 因为老师叫他了

第二个问题:为什么你们不站起来呢?因为其他人不是张三。

张三周围的所有人都收到了那句话,但是不做处理,因为所有人都认为是老师在和张三进行1对1通信,和我们其他人没有关系。张三就站起来,说因为昨天拉肚子了,所以就没有写。张三和老师说的话,其他人也都听到了。但是其他人也都认为不需要给张三应答,因为张三是给老师说的。所以老师和张三在教室内,互相叫着彼此的名字互相通信的过程就叫做我和张三在局域网内一对一进行通信。看起来是进行1对1通信,实际上是有很多的吃瓜群众在围观的,虽然大家并不关心。

回到上面那张图,B主机是要给G主机发消息,首先B主机要把自己的报文,自顶向下封装发送到局域网中,B主机把数据经过网卡,然后经过局域网网线把数据发出来。这根线上面都是跑的光电信号,当B主机在发送数据的时候,可能A主机也在发送数据,就好比,刚刚你在问,张三为什么你的作业没有完成,就有可能李四同时问老师说,老师我有一道题不会。因为在教室这个场景中,所有的教室资源是被教室的所有同学包括老师共享的。而在局域网中,这根网线,也就是这个网络资源被大家共享。所以局域网就要求,当B主机发消息的时候,任何一个时刻,只允许有一个人向网络中发消息,当B发出消息后,此消息是能被所有人接收到的,只不过B主机发出去的报文,内部携带了一个报头字段,报头里面携带了一种地址,叫做mac地址。类比在教室老师叫张三,只有张三一个人站起来了,因为每个人都有名字,就好比局域网内所有的主机都有自己唯一的mac地址,A主机叫做macA,以此类推。所以B主机发消息要发给G,B主机填的mac地址就是macG,填完之后,所有人都收到了,但所有人都在报文做解析对比的时候,比如A主机收到了,但是A发现这个报文是给G的,不是给我的,A主机就把B主机发出的报文直接进行丢弃,C,D,E,F全部丢弃,只有G接受了,所以在局域网中就看作了单向的B把数据发给了G。同样的G主机回应B主机也采用的是同样的道理。归根结底是因为局域网中,网络资源是被大家共享的。

以太网通信原理

在教室里面,你说一句,我说一句,彼此之间我们都在说,比如早读,谁的声音也听不清楚,这就是在一份共享资源里,大家同时发消息。在网络里,如果同时发送可能会发生数据碰撞的问题,一旦碰撞了,相当于我们同时向这个共享资源里发消息了,这个肯定是不行的,但是这个是很难避免的,虽然避免不了,但是我们能够检测到有没有发生碰撞,B主机把消息发出去了,A主机也发出消息了,此时就发生碰撞了,出现互相干扰,因为他们是光电信号,0,1纠缠在一起就区分不出来了,B发出信息后,所有的主机包括自己都能接收到我发的报文,好比我自己说的话我能听到,我先发出去数据,然后我再收回来数据,我发现我说的和我听的不一样了,就发生碰撞了。所以每台主机都要有碰撞检测的能力。相当于一旦发生碰撞了,每台主机都知道,因为要保证正常通信,所以每台主机都要有碰撞避免算法。(就好比你正在说话,发现另一个人也在说,你就等他说完我在说)我们经过这样的调整就能保证任何一个时刻,几乎只有一个人在局域网中发消息。上面这一大堆都在数据链路层帮助我们做了。

局域网中任何一个时刻,都只能有一台主机在向局域网中发送消息。如果有两台以上一定发生碰撞,只要发生碰撞了,那么发送数据的参与通信的两台主机必须要执行碰撞检测和碰撞避免,检测到并且等一等,等待期间别人就可以发。这就是以太网的通信原理。

网络中的互斥 

所有的主机都有可能向一个被大家所共享的资源放数据,那么我就可以把局域网的这根网线想象成一种被大家共享的资源,在每一个主机的视角当中,这个公共资源就是局域网,一个公共资源可能被多个执行流访问,这里的执行流就是多台主机,所以这一份被大家公共访问的资源叫临界资源。

因为这个局域网的网络资源被大家共享,在局域网中,我们只想让一台主机往我们的相关资源中放对应的数据,这个资源是共享的,一旦有两个以上的资源放就发生碰撞,让后我们直接碰撞检测过程杜绝多个主机向局域网中投放数据的这种场景,任何时刻只能有一个人,这种资源被大家共享,有可能被大家同时访问。我们可以把局域网的网络资源理解成临界资源,把A,B,C...若干台主机看做访问临界资源的执行流,那么就相当于任何时候只允许有一个人访问我们的临界资源呢?所以我们碰撞避免的策略,归根结底是为了保证在任何时刻,只能有一台主机在局域网中发消息。这就叫做互斥。

如果我想攻击这个局域网,我该怎么做?

本质就是一直占用临界资源。就好像老师在教室上课,但是我就想干扰老师上课,老师在上面讲,我就可以一直说,“老师讲的真好”,“老师讲的真棒”...你一直向局域网中发消息,最终你就在一直占用这个局域网,此时在系统角度,此时就造成了其他主机的饥饿问题。也就相当于其他主机无法把数据发出,你就成功攻击它了。ps:网络上这种攻击局域网的工具一定会绕开碰撞避免算法,相当于从网络层,然后绕开数据链路层的碰撞避免检查算法,直接向以太网中发消息。

局域网通信过程中数据会泄露吗?

那此时还存在一个小问题,假设B和G主机在通信,它俩以为就是它俩在单独通信,实际上在同一局域网的所有主机都能收到俩人通信的信息,周围存在一大批的吃瓜群众。只不过是其他主机把数据丢弃罢了,底层丢弃,上层就不知道了。但是如果有一天,假如A主机,不丢弃任何报文,那么B和G发送的报文,A主机也去全能抓到。这是可以做到的,比如很多的抓包工具。其实在局域网通信时,我们的数据就是在裸奔。但是现在主流的通信场景都是加密的,即便是把数据拿到了,也不影响。

网络的角度:就叫做局域网资源被大家共享,发数据是只能有一个人独占这个资源。系统的角度:这个局域网就是临界资源。

令牌环的局域网通信原理

令牌环,就相当于每台主机需要传导一部分数据,我们把某个数据我们可以形象的称之为令牌,只有具有令牌的人才能向局域网中发消息,当你发完的时候,你把令牌继续交给下一个主机...这个令牌就像互斥锁中的那把锁。

总结:A主机和路由器,路由器和B主机,就相当于不同的局域网,所以以太网就是基于碰撞检测的方式,令牌环就是基于令牌的方式来进行在局域网中任何时刻,允许一个人通信。但是以太网和令牌环网在最底层这部分是不一样的。

网络中的地址管理


实际上在我们的网络里存在两种地址,一种是ip地址,另外一种是Mac地址。

认识 IP 地址
IP 协议有两个版本 , IPv4 IPv6. 博主的文章 凡是提到 IP 协议 , 没有特殊说明的 , 默认都是指 IPv4
  • IP地址是在IP协议中, 用来标识网络中不同主机的地址;
  • 对于IPv4来说, IP地址是一个4字节, 32位的整数;
  • 我们通常也使用 "点分十进制" 的字符串表示IP地址, 例如 192.168.0.1 ; 用点分割的每一个数字表示一个字节, 范围是 0 - 255;
认识 MAC 地址
  • MAC地址用来识别数据链路层中相连的节点;
  • 长度为48, 6个字节. 一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)
  • 在网卡出厂时就确定了, 不能修改. mac地址通常是唯一的(虚拟机中的mac地址不是真实的mac地址, 可能会冲突; 也有些网卡支持用户配置mac地址).

Mac地址

Mac地址是一种全球内,唯一的,可以捎进网卡内部的一个序列号,它在全球内是唯一的,48位的mac地址更多的用于做局域网标识,在局域网内标识一台唯一的主机。它不做全球化的使用,全球化的使用,用的最多的标识叫做IP地址。

关于ip和mac地址

我们以一个故事展开,西游记中有一个和尚,不管事谁问他,“你从哪来,要到哪去啊”和尚永远说的是,贫僧从东土大唐而来,要去西天拜佛求经。比如唐僧到了,女儿国,女儿国国王问他:“你从哪来,要到哪去啊”。唐僧说"贫僧从东土大唐而来,要去西天拜佛求经".借着唐僧问女儿国国王,我要去西天了,那么下一站应该去哪里呢? 女儿国国王说:向西走,下一站供你落脚的地方在车迟国,下一站你去车迟国。然后唐僧带着他的四个宠物,就向西走到了车迟国。车迟国国王问他:“你从哪来,要到哪去啊”。唐僧说"贫僧从东土大唐而来,要去西天拜佛求经".车迟国国王又问你上一站是从哪来的呢?唐僧说从女儿国。车迟国国王定睛一想,说唐僧啊,下一站,你可有危险了,下一站要去黑风岭,要小心。

唐僧身上是可以有几套地址的呢?

两套。

第一套:叫做从哪里看来,到哪里去(几乎是一直不变的)这个就是IP(对下一站去哪里明显具有指导意义的)

第二套:上一站从哪里来,下一站去哪里(一直在变化)这个就是mac(一直在变化的地址)

一直在变化围绕的一直不变展开的。唐僧一路变着不同的地址,不同的城池,去着不同的地方,但是不变的是一直要去西天。

所以我们在正常情况下,进行正常路由的时候,一般目的ip是不变的,目的mac是一直在变的,为什么mac在变呢?

因为你要去的ip地址一直没变。就好比你要去云南玩,你从内蒙古出发,你要去的下一站就是山西,陕西等直到到达云南。你的最终目的决定你阶段性的mac地址。

每台主机都有它的mac地址,路由器也是一台主机。

唐僧问女儿国国王,要去西天取经,实际上是根据唐僧的IP地址,严格意义是根据唐僧的目的IP,去问女儿国国王,女儿国国王就相当于一台路由器,根据自己的经验和唐僧要去的ip告诉唐僧下一站要去车迟国,这个具体的Mac地址。实际上我们进行数据包转发的时候,数据包,自顶向下不断进行封装,到了以太网这里,它的报头里有很多字段,这里我们说两个重要的字段。一个src(源),一个dst(目的),代表的是Mac地址。因为大家都在同一个局域网,当前主机和路由器主机都收到这个报文,然后根据路由器收到的报文,在它的以太网驱动程序和令牌环驱动程序,这一层进行解包分用。把报头和有效载荷进行分离,因为dst是路由器的Mac地址,所以只有路由器收到了(其他主机检测到这个dst不是他们自己,所以都丢弃这个报文),收到之后路由器就进行解包分用,完成之后向上交付,交付给ip,ip的有效载荷里面也有ip,这里要做路由工作。路由的时候又发现你要到目的主机B,然后在路由器里面,在从上到下封装,这次封装,封装的是令牌环的报头,然后被B主机收到,之后进行解析报头,向上进行交付。

mac地址一直在变化,因为在数据链路层,经过路由器,一直在进行解包和封装。根据目的Mac地址一直在进行封装,所以你的Mac地址一直在变化。

ip的意义

站在ip层,因为有路由器的存在,发送方发送的就是这个数据(如图的有效载荷),路由器收到的也是这个数据(如图的有效载荷),对方收到数据的主机也是这个数据(如图的有效载荷)。在ip层及其ip层往上的所有协议就看不到底层网络的任何差异,站在ip层角度,主机A的ip层发什么,主机B的ip层就收什么,没有不同。因为路由器给我们屏蔽了底层网络的差异,所有互联网底层核心的协议叫做ip,将来有10000个局域网也都不影响,因为ip层以上都叫做ip网络。ip的存在可以将所有的不同网络进行大一统,有点像ip就是一种局网络的虚拟化技术。ip因为路由器的存在,ip存在的最大意义之一就是屏蔽了底层网络的各种差异,能够保证在ip及其往上看到的都是同一个网络。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值