计算机最初一定是相互独立的。但我们由很多工作需要相关协作完成,当时的解决办法是用某些硬件将数据进行拷贝交给其他人。但该过程中设计到人力,一旦设计到人力必然导致效率下降。这也为的诞生埋下伏笔!
后来的诞生,让多台计算机连接在一起,数据共享,实现互联。随着计算机的数量越来越多,我们通过交换机和路由器将众多的计算机全部链接起来,构成了局域网LAN。但随着局域网的产生,我们来需要将相隔千里的计算机链接起来,比如将中国和美国的一些计算机连接起来,由此广域网的概念诞生!
的诞生本质上还是用于不同的主机间的相互通信。而在每台计算机内部,硬件之间的数据拷贝交换本身就是一种通信行为,而每台计算机中硬件的个数是有限的,并且由OS管控!而不同机器间通信,就是不同机器上的网卡间的相关通信。两者也是硬件间的通信,根本在于后者通信的距离变长,并且中间会经过其他众多设备!
距离变长,经过众多设备比如会导致如下问题:
- 如何保证数据准确的由一跳交给下一跳?
- 在转发过程中,如何查找路径,定位目标主机?
- 如果转发过程中发生数据丢包,如何解决?
- 向目标设备发送数据成功后,目标设备如何使用接收到的数据?即如何处理接收到的数据?(即接收到的信息很杂,如何分辨处理这些信息)
为了解决上述问题,OSI(Open System Interconnection,开放系统互连)定义出了相关协议 —— 协议栈!而协议本质上就是一种约定,每一种约定对于上述一种问题的解决办法!软件上,绝大部分优秀的软件都是分成的,这不仅可以完成不同软件间的解耦合,未来也非常方便对软件进行维护、更新、替换和优化等!每一层协议解决不同问题,从而将进行分层。从逻辑上分为了7层. 每一层都有相关、相对应的物理设备!
OSI定义成了七层,但实践一般分为5层!
- OSI 七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型的主机实现数据传输,它的最大优点是将这三个概念明确地区分开来,概念清楚,理论也比较完整!
- 但实际过程中,应用层、表示层、会话层三层很难单独分开,因此将这三层统称为应用层。即右边CP/IP五层模型!!
每一层协议解决的问题如下:
由于TCP/IP在OS中,处于核心地位,因此我们将TCP/IP作为一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇。TCP/IP中,各层功能如下:
- 物理层: 负责光/电信号的传递方式. 比如现在以太网通用的网线(双绞 线)、早期以太网采用的的同轴电缆(现在主要用于有线电视)、光纤, 现在的wifi无线网使用电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等. 集线器(Hub)工作在物理层.
- 数据链路层: 负责设备之间的数据帧的传送和识别. 例如网卡设备的驱动、帧同步(就是说从网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、数据差错校验等工作. 有以太网、令牌环网, 无线LAN等标准. 交换机(Switch)工作在数据链路层.
- 层: 负责地址管理和路由选择. 例如在IP协议中, 通过IP地址来标识一台主机, 并通过路由表的方式规划出两台主机之间的数据传输的线路(路由). 路由器(Router)工作在网路层.
- 传输层: 负责两台主机之间的数据传输. 如传输控制协议 (TCP), 能够确保数据可靠的从源主机发送到目标主机.
- 应用层: 负责应用程序间沟通,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、远程访问协议(Telnet)等. 我们的编程主要就是针对应用层
对于一台主机,部分核心物理设备为网卡,数据链路层工作在网卡的驱动程序中。在往上,层和传输层则是工作在操作系统中!再网上就到了用户层!
所以对于一个合格的OS,不仅要实现内存管理、进程管理、文件管理以及驱动管理等工作,还需实现协议栈中的两层:层和传输层!当用户需要进行通信时,不能直接访问网卡设备,而需要贯穿操作系统;而贯穿操作系统本质就是在贯穿协议栈。而最核心的层和应用层是在OS中实现的,所以用户需要使用协议栈,本质就是在使用操作系统!所以OS要基于tcp/ip为我们提供对应的系统调用接口!
不同的操作系统的内核实现可能差别很大,但对于协议的实现是基本一样的,尤其是传输层和层!相当于每台计算机都遵循相同的协议,相关的约定,从而保证所有计算机之间都能顺利通信,使得不同操作系统的主机能够进行可靠的通信!
在实际生活中,我们收到的快递除了物品本身外,还包含快递单。快递单中回填从相关信息:有谁发的,从哪里发给哪里…这些数据收和发两者都知道认识,更多的是给物流体系知道,指导快递的发送!所以长距离运输,快递 = 内容 + 快递单。而快递单本身就是一种约定,为接收双发知道,是一种协议,我们将之称为报头!
收快递的过程中,实际收到的要比期望收到的东西要多,多出来的部分称为报文。而在计算机通常是由一个结构化字段表征,这个结构化字段定义的对象称为协议报头!
1)两台主机通信原理
在同一个作用域中,两台主机是可以直接发消息的!每台主机都存在一个网卡设备,在全球中每台计算机的网卡Mac地址都是唯一的。主机A向主机B发送消息"你好"时,除了内容本身,还包含相关协议。而协议中包含接收主机的Mac地址和发送主机的Mac地址。
当主机A将数据发到局域网中时,当前局域网中的所有主机网卡设备都会收到该消息。但其他网卡收到消息后,发现接收方的Mac地址不是自己后会直接丢弃!但某一时刻,可能多台主机同时向局域网中发送消息,此时数据会发送碰撞,导致数据失效,而此时的局域网也被称为碰撞域。此时发送方会执行碰撞监测算法(在随机时间后重新发送)。即要正确的发送数据,任何时刻局域网中只允许一台主机在局域网中发送消息!
- 这种基于碰撞域、碰撞监测、碰撞避免的通信方式,并且碰撞是概率的。我们将这种局域网称为以太网!
- 碰撞域本身就是一个临界资源,而碰撞监测、避免和重发完成的就是互斥访问临界资源!
2)两台主机通信过程
两台主机通信发送消息“你好”时,是通过网卡设备通过以太网推送给另一台主机的网卡设备的。所以需要贯穿协议栈,然后从上往下依次添加对应层的协议报头。当目标主机网卡接收到消息后,会从下往上依次解析,将报头和有效载荷进行分离,将有效载荷逐次传给上一层进行分用。
- 报文 = 报头 + 有效载荷。应用层报文称为;传输层报文称为;层报文称为;数据链路层报文称为。
不同的协议层对数据包有不同的称谓,在应用层报文称为;在传输层报文称为;在层报文称为;在数据链路层报文称为!
应用层数据通过协议栈发到上时,每层协议都要加上一个数据首部(header),称为封装!疯转一定要考虑后续解包过程:①如何将报文中有效载荷和报头分开②如何将自己的有效载荷交给上一层那个协议。所以首部信息中包含了一些类似于首部有多长, 载荷(payload)有多长, 上层协议是什么等信息。
数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部, 根据首部中的 “上层协议字段” 将数据交给对应的上层协议处理!