目录
网络的位置
在体系结构中,网络在什么位置嘞?
协议栈是什么东西嘞?
为甚么要分层呢?
计算机网络背景
独立模式
网络互联
局域网LAN
广域网WAN
认识协议
网络协议初始
协议分层
OSI七层模型
TCP/IP五层(或四层)模型
网络传输基本流程
跨网络的两台主机通信
网络中的地址管理
认识IP地址
认识MAC地址
我们经常使用的软件(手机软件,电脑软件实际上都处在应用层),通过应用层软件下发的指令,最终会下发到操作系统,操作系统有自己内嵌的协议栈,通过协议栈的层层“封包”,将下发的指令打包成报文,通过网络传输到相应的服务器里面,服务器也是一个操作系统,也有自己的协议栈,通过对报文的层层解包,拿到指令,处理完数据以后,再打包,通过网络传输,返回处理以后的结果。
需要注意的是,不同操作系统的进程管理、文件管理、内存管理、驱动管理的实现方式可能是不一样的。比如Windows和Linux实现多线程的方式是不一样的,Linux当中的线程是用轻量级进程模拟的,而Windows当中是有真正意义上的线程的。
而协议栈是由网络标准化组织定义的,所有的操作系统都得遵从这样的协议,所有的操作系统也必须支持。对于协议栈的细节处理也都是相同的。对数据的封包和解包操作都遵循这样的方式。
我们都知道OS的主要目的是管理,操作系统有多种管理方式,文件管理,进程管理,内存管理,驱动管理,操作系统层与应用层之间还有系统调用层,操作系统层下面就是驱动层,驱动层往下就是硬件层,
操作系统管理各种软硬件资源,对上提供一个良好的稳定的运行环境,
操作系统中除了有这四大管理模块,还有与网络协议栈有着密切的关系。
网络协议栈主要负责数据的通信,其自顶向下可分为四层,分别是应用层、传输层、网络层、数据链路层。
如下图所示,
应用层:是由相关的网络协议的开发者来编写的,比如http https等协议,其主要作用在于根据协议的不同,对数据进行分析处理,达到某目的
传输层:主要作用在于对传输过程的问题进行解决,主要保证数据传输的可靠性
网络层:主要负责数据传输到哪里的问题,保证数据传输的目的。
数据链路层:负责物理层的数据传输问题,负责数据真正的发送过程。
如图所示:
层状结构的本质是软件工程上面的解耦,此时层与层之间只有接口的相互调用关系,此时可以让
研究不同的问题的人分离开来,最后通过编码实现接口的调用,宏观上代码的可维护性和可扩展性变高,微观上,专业的人负责专业的事,使得代码的性能变高。
计算机之间相互独立,每个终端执行任务以后,通过拷贝到硬盘等方式,再给其他终端执行其他任务。
在早期的时候,计算机之间是相互独立的,此时如果多个计算机要协同完成某种业务,那么就只能等一台计算机处理完后再将数据传递给下一台计算机,然后下一台计算机再进行相应的业务处理,效率非常低下。
多台计算机连接在一起, 完成数据共享;
通过总线将数据传输到服务器里面,这样就可以在业务1-3之间来回切换。
计算机数量更多了, 通过交换机和路由器连接在一起。
在局域网中有一种设备叫做交换机,交换机主要完成局域网内数据的转发工作,也就是在局域网内将数据从一台主机转发给另一台主机。各个局域网之间通过路由器连接起来,路由器主要完成数据的路由转发工作。
将远隔千里的计算机都连在一起;
广域网和局域网是一个相对的概念,大的局域网也可称之为广域网。
协议是一种约定,只有所有的操作系统都遵从这种约定,双方才能通信,在系统层面上,通过代码对协议进行规定,操作系统都遵守,计算机才能识别约定的相关内容。
举个例子
比如通信计算机双方曾经做过如下约定:
就是一个位段结构,我们是可以通过位段来表示某种协议规定的,而实际上计算机网络里面的协议报头也就是通过位段来实现的。
有了这样的约定后,当甲计算机向乙计算机发送类似于{1, 0x1234}的数据时,乙计算机识别到code的值是1,于是就知道了甲计算机是让自己将data的值存储进数据库,这是一种纯软件的约定方案。
另外我们应该都知道,计算机之间的传输媒介是光信号和电信号,通过“频率”和“强弱”来表示0和1这样的信息,因此要想传递各种不同的信息,就需要约定好双方的数据格式,这就是一种纯硬件的一种约定方案。
协议应该由谁定制:
行业的翘楚公司,大部分人都认同你这个东西,比如华为的5G协议,就是大家都认同,因为华为是通信行业的翘楚公司,5G的协议也定制,大多数人都认同。
网络协议栈设计成层状结构,其目的就是为了将层与层之间进行解耦,保证代码的可维护性和可扩展性。
比如打电话:
站在工程师的角度,先把说的话,进行记录,通过一系列编码,转码,再经过系统进行封包,发送数据到对应的接收方,对方通过一系列转码和编码进行拆包,读取数据,再传达给接收的人,
其转码与编码有自己的协议
传输有自己的协议,
其中,人与人之间通信使用的是汉语,我们可以将其称为语言层;而电话和电话之间通信使用的是电话系统相关的一些接口,我们可以将其称之为通信设备层
随着科技的发展,后续的设备改了,但实际上底层协议并没有改变,所以,我们仍然可以继续沟通。
分层最大的好处在于“封装”,在分层情况下,将某层的协议进行替换后,通信双方之间是不会受到影响的。
理解同层之间直接通信
在上述例子中,虽然经过了多层时间的封包和解包的过程,但实际上我们在打电话的时候会认为我们和对方直接沟通的,
所以在理解各层通信的时候也可以认为通信双方都是各层之间相互通信的,从而简化了协议栈的理解过程。
也就是说,在网络协议栈中我们可以认为通信双方的应用层之间直接在进行通信,也可以认为通信双方的传输层之间直接在进行通信,对于网络层和数据链路层也同样如此。
1,OSI(Open System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型,是一个逻辑上的定义和规范;
2,把网络从逻辑上分为了7层. 每一层都有相关、相对应的物理设备,比如路由器,交换机;
OSI 七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型的主机实现数据传输;
3,它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整. 通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯;
但是, 它既复杂又不实用; 所以我们按照TCP/IP四层模型
TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇.
TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求.
1.物理层: 负责光/电信号的传递方式。比如现在以太网通用的网线(双绞线)、早期以太网采用的同轴电缆(现在主要用于有线电视)、光纤,现在的WiFi无线网使用的电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等。集线器(Hub类似于信号放大器,在传输的过程中,信号会衰弱,为了保证信号的正确性,需在一段距离中放大信号)就是工作在物理层的。
2.数据链路层: 负责设备之间的数据帧的传送和识别。例如网卡设备的驱动、帧同步、冲突检测(如果检测到冲突就自动重发)、数据差错校验等工作。数据链路层底层的网络通信标准有很多,如以太网、令牌环网、无线LAN等。交换机(Switch,局域网内的数据转发)就是工作在数据链路层的。
3.网络层: 负责地址管理和路由选择。例如在IP协议中,通过IP地址来标识一台主机,并通过路由表的方式规划出两台主机之间数据传输的线路(路由)。路由器(Router,链接不同的局域网)就是工作在网络层的。
4.传输层: 负责两台主机之间的数据传输。例如传输控制协议(TCP),能够确保数据可靠的从源主机发送到目标主机。
5.应用层: 负责应用程序间沟通。比如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet等)。我们的网络编程主要就是针对应用层的。
物理层我们考虑的比较少. 因此很多时候也可以称为 TCP/IP四层模型
一般而言
对于一台主机, 它的操作系统内核实现了从传输层到物理层的内容;
对于一台路由器, 它实现了从网络层到物理层;
对于一台交换机, 它实现了从数据链路层到物理层;
对于集线器, 它只实现了物理层;
但是并不绝对. 很多交换机也实现了网络层的转发; 很多路由器也实现了部分传输层的内容(比如端口转发);
以太网名字的由来
“以太网”这个名字实际来源于物理学,在早期的时候,很多科学家都认为任何信息的传播都是需要媒介的,因此物理学家们就认为光的传播也是需要媒介的。这时物理学家们就发现了一个问题:既然光能够从太阳传播到地球上,那么在这个传播的过程中一定需要某种媒介,但太阳和地球之间不是绝对真空的状态吗?
此时物理学家们就提出了一个“以太假说”,认为宇宙空间并不是真空的,而是填充满了一种叫做“以太”的物质的,此时“以太”就可以作为光传播的媒介。但后来经过实验后发现,“以太”这种物质实际上是不存在的。
其中在这个故事线当中有两个人是与计算机学科相关的,一个人叫做图灵,另一个叫做冯诺依曼,这两个人当时也是参与了这场讨论的,因为他们不仅是计算机科学家,同时也是数学家。
经过后来的发展,在局域网产生之后就需要对局域网进行命名,而在局域网命名的时候人们就将其命名为“以太网”。因为我们曾经在物理学上认为“以太”就是传送物质的介质,也就是说“以太”是具有某种通信能力的,虽然“以太”在物理学上验证是不存在的,但现在在计算机领域我们做出来了这样一种东西,它也是能够传播物质(信息)的,同时也为了纪念之前的“以太假说”,于是早期的局域网标准就被命名为了“以太网”。
同一个网段内的两台主机进行文件传输
同一局域网下面通讯的过程
当用户把数据交给操作系统以后,操作系统会做如下操作
1,数据交给应用层 --应用层添加当前层的报头信息--将数据交给下一层
2,传输层收到数据---传输层加报头信息--再讲数据交给下一层
3,网络层收到数据--网络层加报头信息---把数据交给下一层
4,数据链路层收到数据--数据链路层加报头信息--把数据通过网络发给接收方,至此数据封包完毕
接收方收到数据以后,接收方做如下事件
1,数据交给数据链路层 --数据链路层去掉当前层的报头信息--将数据交给上一层
2,网络层收到数据---网络层去头信息--再把数据交给上一层
3,传输层收到数据--传输层加报头信息---把数据交给上一层
4,应用层收到数据--应用层去报头信息--把数据交给要操作的地方,至此数据解包与分用完毕
数据包封装与分用
1,不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报 (datagram),在链路层叫做帧(frame).
2,应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装
(Encapsulation).
3,首部信息中包含了一些类似于首部有多长, 载荷(payload)有多长, 上层协议是什么等信息.
4,数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部, 根据首部中的 "上层协议字段" 将数据交给对应的上层协议处理.
数据封装的过程
下图为数据分用的过程
什么是报头
报头本质也是一种数据,报头一般通过位段实现,在协议栈的每层都会加上报头,也就是说每一层都会加上位段的数据。
数据的封装与解包
数据封装:实际上就是给数据在每层加上相应的报头,这些报头里面添加是各种协议细节
数据解包:实际就是不断从数据中提取对应的报头,并对提取出来的报头进行数据分析。
报头与有效载荷
当对端主机收到数据后,需要自底向上贯穿协议栈,依次进行数据的解包与分用。在这个解包的过程中,每一层的协议只需要提取出数据中对应的报头,然后对该报头进行分析处理,而剩下的数据则直接交付给上层就行了。
因为每一层的协议实际上只关心数据中与当前层对应的报头信息,而剩下信息的具体内容根本不必关心,我们将数据中除当前层的报头以外的数据叫做“有效载荷”。
需要注意的是,上层协议在数据封装时添加的报头信息,在下层协议进行数据解包时看来就是有效载荷。比如数据封装时应用层添加的报头信息,在对端主机进行数据解包时,在对端主机的传输层、网络层以及链路层看来,该应用层曾经添加的报头信息就是有效载荷
如何将报头与有效载荷进行分离?
协议栈的每一层都要从数据中提取对应的报头信息,而要将数据中的报头提取出来,首先就需要明确报头与有效载荷之间的界限,这样才能将它们进行分离。而每一层添加报头时都是将报头添加到数据的首部的,因此我们只要知道了报头的大小,就能够讲报头和有效载荷进行分离。
1.获取报头大小的方法通常有两种:
2.定长报头。顾名思义就是报头的大小是固定的。
自描述字段。报头当中提供了一个字段,用来表示报头的长度。
实际上每个协议都要提供一种方法,让我们获取到报头的大小,这样我们才能在解包时将报头与有效载荷进行分离。
当前层如何知道应该将有效载荷交付给上层的哪个协议?
网络协议栈的每一层都可能会对应多种协议,即便将报头与有效载荷分离了,那当前层应该将有效载荷交付给上层对应的哪个协议呢?
实际在每种协议的报头当中,几乎都会包含一个字段,表明我们应该把分离出来的有效载荷交付给上层的哪个协议,这就是分用的过程。
协议共性
1,提供一个将报头与有效载荷分离的方法。
2,协议当中必须包含一个字段,表明应该将有效载荷交付给上层的哪个协议。
实际当我们要学习一种协议的时候,首先就应该明确这两点,因为当我们在解包的时候必须将报头与有效载荷分离,而当我们在分用的时候必须知道应该将有效载荷交付给上层的哪个协议
局域网内传输数据时,该局域网内的所有主机都能收到
在一个局域网当中,除了当前正在进行通信的A主机和B主机以外,还有其他的主机,那A主机是如何将数据成功发送给B主机的呢?
实际当主机A想要发数据给主机B的时候,该局域网内的其他主机也都收到了该数据,只不过除了主机B以外,其他主机识别到该数据并不是发给自己的,此时其他主机就把收到的数据丢弃了。
也就是说,在局域网(以太网)通信时,该局域网内所有的主机在底层其实都收到了任何数据,只不过经过筛选后只提交上来了发给自己的数据。
什么是碰撞?
当主机A在向主机B发送数据时,其他主机彼此之间可能也正在进行通信,甚至主机A在和主机B通信的同时也在和其他主机进行通信
但同一局域网中的所有主机在通信时,使用的都是一个共同的通信信道,因此如果局域网内的多台主机同时进行通信,此时这些数据之间就可能会相互干扰。
每一个局域网都可以看作是一个碰撞域,如果某个主机发送出去的数据与其他主机发送的数据之间产生了干扰,我们就称这两台主机在该碰撞域中发生了碰撞。
如何判断发送出去的数据是否发生了碰撞?
因为发送到局域网当中的数据是所有主机都能够收到的,因此当一个主机将数据发送出去后,该主机本身也是能够收到这个数据的。当该主机收到该数据后就可以将其与之前发送出去的数据进行对比,如果发现收到的数据与之前发送出去的数据不相同,则说明在发送过程中发生了碰撞。
也就是说,主机实际是能够通过某种方式,知道曾经发送出去的数据是否发生了碰撞的
发生碰撞后是如何处理的?
当一个主机发现自己发送出去的数据产生了碰撞,此时该主机就要执行“碰撞避免”算法。“碰撞避免”算法实际很简单:当一个主机发送出去的数据产生了碰撞,那么该主机可以选择等一段时间后,再重新发送该数据。这就像现实生活中的两个人同时想要说话,此时对方就都会说“你先说吧”,这实际上就是一种碰撞避免。
需要注意的是,实际在网络通信压力不大的时候发生碰撞的概率是不大的,我们不要太小瞧计算机的处理速度,也不要太小瞧网线传播数据的速度。
每个主机如何判断该数据是否是发送给自己的?
在局域网中发送的数据实际叫做MAC数据帧,在这个MAC数据帧的报头当中会包含两个字段,分别叫做源MAC地址和目的MAC地址。
每一台计算机都至少配有一张网卡,而每一张网卡在出厂时就已经内置了一个48位的序列号,我们将这个序列号称之为“MAC地址”,这个MAC地址是全球唯一的。
在局域网中进行通信的时候,每一个主机在收到一个MAC数据帧后,都会提取该MAC数据帧的报头,找到对应的目的MAC地址与自己的MAC地址进行比对。如果该MAC地址与自己的MAC地址不匹配,则直接将该MAC数据帧丢弃,只有MAC地址匹配时,该主机才会将该数据帧的有效载荷继续向上进行交付处理。
单向数据发送: 主机发送数据帧时,将数据帧当中的目的MAC地址指定为某一台主机,此时每台主机对数据帧进行识别后,最终只有那台指定的主机会将该数据帧向上交付进行处理。
局域网内进行数据广播: 主机发送数据帧时,将数据帧当中的目的MAC地址设置为全1,此时所有主机收到该数据帧后都会对该数据帧进行处理
上面说的都是同一局域网内的主机之间的通信,那跨局域网的两台主机之间是如何进行通信的呢?
局域网之间都是通过路由器连接起来的,因此一个路由器至少能够横跨两个局域网。而这些被路由器级联局域网都认为,该路由器就是本局域网内的一台主机,因此路由器可以和这些局域网内的任意一台主机进行直接通信。
比如局域网1当中的主机A想要和局域网2当中的主机H进行通信,那么主机A可以先将数据发送给路由器,然后路由器再将数据转发给局域网2当中的主机H。
采用不同通信标准的两个局域网内的主机通信
如果路由器级联的两个局域网采用的是相同的通信标准,那么通信过程大致就是上述那样。但被路由器级联的局域网可能采用的是不同的通信标准,比如局域网1采用的是以太网,而局域网2采用的却是令牌环网
由于以太网和令牌环网是不同的通信标准,它们给数据添加的报头也是不一样的,因此令牌环网当中的主机无法对以太网当中的数据帧进行解包。
这种情况实际是由路由器来处理的,路由器是工作在网络层的一个设备,我们可以认为路由器当中的协议栈是下面这样的
此时当数据要从局域网1发送到局域网2时,路由器收到局域网1的数据后,会先将以太网对应的报头进行解包,然后将剩下的数据向上交付给网络层,在网络层进行一系列数据分析后,再将数据向下交付给链路层,此时在链路层当中就会给该数据添加上令牌环对应的报头信息,然后再将该数据发送到局域网2当中,此时该数据就能够在令牌环网当中传输了。
路由器为什么能够“认路”?
一个路由器可能会级联多个局域网,当路由器需要将一个局域网的数据转发到另一个局域网时,路由器如何知道该数据应该转发到哪一个局域网的呢?
路由器其实是通过IP地址来确定数据的转发方向的,因特网上的每台计算机都有一个唯一的IP地址,而在数据向下进行封装时,在网络层封装的报头当中就会包含两个字段,分别是源IP地址和目的IP地址。
当路由器需要将一个局域网的数据转发到另一个局域网时,在路由器的链路层会先将数据的在当前局域网对应的底层报头去掉,然后将剩下的数据向上交付给网络层,此时在网络层就可以获取到该数据对应的目的IP地址,然后路由器就可以根据该IP地址在路由表当中进行查找,最终就能够确认该数据应该发送到哪一个局域网
屏蔽底层的差异
IP地址的存在除了帮助数据“路由”以外,还有一个很重要的作用,那就是屏蔽了底层网络的差异。对于通信主机双方的IP层及其往上的协议来说,它们并不需要关心底层采用的是以太网还是令牌环网,它们认为只要填写了源IP地址和目的IP地址就能够将数据发送出去,因此现在主流的网络也叫做“IP网络”。
这种类似的技术还有:
虚拟地址空间: 屏蔽了内存之间的差别,让所有的进程看到的都是同一块内存,并且这块内存的布局都是一样的。
一切皆文件: 通过文件结构体和函数指针的方案,让我们能够以对待文件的方式对待某些资源。
1,IP地址是在IP协议中,用来标识网络中不同主机的地址。
2,对于IPv4来说,IP地址是一个4字节,32位的整数。
3,我们通常也使用“点分十进制”的字符串表示IP地址,例如192.168.0.1,用点分割的每一个数字表示一个字节,范围是0-255。
需要注意的是,IP协议有两个版本,分别是IPv4和IPv6。IPv4用32个比特位来标识IP地址,而IPv6用128个比特位来标识IP地址。
1,MAC地址用来识别数据链路层中相连的节点。,
2,长度为48位,及6个字节,一般用16进制数字加上冒号的形式来表示(例如:08:00:27:03:fb:19)。
3,在网卡出厂时就确定了,不能修改。MAC地址通常是唯一的(虚拟机中的MAC地址不是真实的MAC地址,可能会冲突,也有些网卡支持用户配置MAC地址)。