一.协议
1.概念
协议(Protocol) 是一组规则和约定,用于定义计算机网络中不同设备之间如何进行通信和数据交换。协议规定了数据的格式、传输方式、传输顺序等详细规则,确保不同设备和系统能够有效地互联互通。
在网络通信中,协议起到了“语言”的作用,确保不同的设备可以理解彼此的“话”。例如,在互联网中,计算机通过协议来传输网页、文件、邮件等数据。
计算机之间的传输媒介是光信号和电信号. 通过 "频率" 和 "强弱" 来表示 0 和 1 这样的
信息. 要想传递各种不同的信息, 就需要约定好双方的数据格式.
2.协议分层
协议本质也是软件,在设计上为了更好的进行模块化,解耦合,也是被设计成为层状结构的。它将通信协议分为不同的层级,每一层负责特定的功能和任务,层与层之间通过接口进行交互。
什么是分层呢?
比如说打电话,我们可以把它分为两层,第一层 语言层通过语言协议不同人间进行交流。
第二层 通信设备层通过电话协议不同电话间进行交流。
复杂任务分解成一系列相对简单的、互不干扰的层,每层都有对应的协议进行约定。
协议分层的好处
模块化设计:每个层只关注其特定的功能,避免了复杂性,易于管理。
便于维护:当出现通信问题时,可以通过定位某一层来快速排查,简化了故障诊断。
灵活性:某一层的协议可以独立改变,不必影响到其他层。
兼容性和标准化:不同厂商和设备可以使用相同的协议层标准,确保互联互通。
二.OSI 七层模型
OSI(Open System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型,是一个逻辑上的定义和规范;
把网络从逻辑上分为了 7 层. 每一层都有相关、相对应的物理设备,比如路由器,交换机;
OSI 七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型的主机实现数据传输;
它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整.在网络角度,OSI 定的协议 7 层模型其实非常完善,但是在实际操作的过程中,会话层、表示层是不可能接入到操作系统中的,所以在工程实践中,最终落地的是 5 层协议。
三.TCP/IP 五层(或四层)模型
TCP/IP 是一组协议的代名词,它还包括许多协议,组成了 TCP/IP 协议簇.
TCP/IP 通讯协议采用了 5 层的层级结构,每一层都呼叫它的下一层所提供的网络来完
成自己的需求.
物理层: 负责光/电信号的传递方式
数据链路层: 负责设备之间的数据帧的传送和识别.网络层: 负责地址管理和路由选择.
传输层: 负责两台主机之间的数据传输.
应用层: 负责应用程序间沟通
物理层我们考虑的比较少,我们只考虑软件相关的内容. 因此很多时候我们直接称为
TCP/IP 四层模型.
四.TCP/IP协议
1.为什么要有 TCP/IP 协议?
1.首先,即便是单机,你的计算机内部,其实都是存在协议的,比如:其他设备和
内存通信,会有内存协议。其他设备和磁盘通信,会有磁盘相关的协议,比如:
SATA,IDE,SCSI 等。只不过我们感知不到罢了。而且这些协议都在本地主机各自
的硬件中,通信的成本、问题比较少。2.其次,网络通信最大的特点就是主机之间变远了。任何通信特征的变化,一定会
带来新的问题,有问题就得解决问题,所以需要新的协议咯。所以,为什么要有 TCP/IP 协议?本质就是通信主机距离变远了,出现了新的问题需要解决。
2.什么是TCP/IP协议?
TCP/IP 协议的本质是一种解决方案
TCP/IP协议和操作系统的关系
不同主机的操作系统不同,但可以相互通信,就是因为所有主机的协议栈都是按标志进行相同实现的。
传输层最著名的协议TCP 网络层最著名的协议IP
而传输层 网络层两层必须实现在内核中,无论OS再怎么不同,这部分都要遵守协议,必须一样。因此,传输层和网络层协议在不同操作系统中确实必须遵循相同的标准,无论操作系统如何实现,它们的核心行为和协议功能应保持一致。
问题:主机 B 能识别 data,并且准确提取 a=10,b=20,c=30 吗?
回答:答案是肯定的!因为双方都有同样的结构体类型 struct protocol。也就是说,用同样的代码实现协议,用同样的自定义数据类型,天然就具有”共识“,能够识别对方发来的数据,这不就是约定吗?
关于协议的朴素理解:所谓协议,就是通信双方都认识的结构化的数据类型
因为协议栈是分层的,所以,每层都有双方都有协议,同层之间,互相可以认识对方的协议。
五.网络传输基本流程
1.局域网(以太网为例)通信原理
首先回答,两台主机在同一个局域网,是否能够直接通信?是的
原理类似上课
每台主机在局域网上,要有唯一的标识来保证主机的唯一性:mac 地址
比如说局域网中连接了5台电脑,其中有一台A电脑向B电脑发信息,会把消息放入局域网中,其它电脑其实也可以接收到,但只要B会处理。为什么,因为每天电脑都有自己唯一的mac地址(MAC 地址用来识别数据链路层中相连的节点),通过比对mac地址来判断是否要处理该消息。
以太网中,任何时刻,只允许一台机器向网络中发送数据
如果有多台同时发送,会发生数据干扰,我们称之为数据碰撞
所有发送数据的主机要进行碰撞检测和碰撞避免
没有交换机的情况下,一个以太网就是一个碰撞域
局域网通信的过程中,主机对收到的报文确认是否是发给自己的,是通过目标mac 地址判定
通过 ifconfig 查看 MAC 地址
在大多数 Unix-like 系统(包括 macOS 和 Linux)中,执行 ifconfig 命令后,你可以看到类似以下的输出:en0: flags=8863<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255ether 00:1a:2b:3c:4d:5e txqueuelen 1000 (Ethernet)media: autoselect 100baseTX status: active...
在这个输出中:
ether 00:1a:2b:3c:4d:5e 就是 MAC 地址,它位于每个网络接口的硬件部分。
MAC 地址是 48 位的十六进制数,通常由六对十六进制数字(如 00:1a:2b:3c:4d:5e)组成。
2.数据包封装和分用
初步明白了局域网通信原理,再来看同一个网段内的两台主机进行发送消息的过程
而其中每层都有协议,所以当我进行进行上述传输流程的时候,要进行封装和解包。
数据包封装:在向下交付的时候每一层都会添加自己的报头,报文 = 报头 + 有效载荷,再把报文向下交付。
数据包分用:在向上解包时,因为同一层有相同的协议,所以能识别报头,它会解开报头,把有效载荷在向上解包。这样就形成了对称的结构。
下面我们明确一下概念:
封装:将自顶向下进行交付的过程称为封装,封装就是添加报头的过程。解包:每一层协议接收到数据后,都会去除该层报头,并将剩余的有效负载交给上一层。
分用:正是将解包后的数据准确地分发给对应的上层协议进行处理。(报头内部,必须包含一个字段,叫做交给上层谁的字段--分用)
报文:是整个数据传输单元,包含报头和有效载荷(数据部分)。
报头:是报文的一部分,包含与数据传输、路由、错误检测等相关的控制信息。报文=报头+有效载荷
六.网络中的地址管理
我们知道在同一个局域网的主机间传输信息,把信息放入局域网中,再根据mac地址的唯一性找到目标主机。但如果两个主机不在同一个局域网中,怎么进行信息交流呢?
当两个主机不在同一个局域网中时,它们无法直接通过 MAC 地址进行通信,因为 MAC 地址仅在同一局域网内有效。为了在不同局域网的主机之间进行通信,我们需要依赖 路由器 和 IP 地址
1. IP 地址和路由器
每个主机都具有唯一的 IP 地址,IP 地址用于确定主机在网络中的位置。当两个主机处于不同局域网时,它们的 IP 地址必定不在同一个子网范围内。因此,它们无法直接通过 MAC 地址进行通信。
路由器负责将来自一个局域网的流量转发到另一个局域网,并确保数据能够跨越不同的子网、不同的网络进行传输。
2.跨网传输过程
1.A向B发信息,主机A从上层不断把信息进行封装(其中包含src:源IP地址 dst:目标IP地址),到了网络层后会检查B的IP是否在同一子网中。
2.如果不在,将封装后数据包发送到其默认网关(即路由器)。
3.路由器对报文进行解包,到了网络层中再检查B的IP地址是否直接连接。
4.如果目标主机B的网络直接连接到默认网关,那路由器把信息再进行封装后,直接发给B。
不直接连接到默认网关的网络,那么信息就必须通过多个路由器进行转发,直到信息到达目标主机B。
1.A怎么把信息发送到默认网关?
在网络层中对报文添加的报头中有src:A主机mac地址 dst:默认网关mac地址
对比 IP 地址和 Mac 地址的区别
IP 地址在整个路由过程中,一直不变(目前,我们只能这样说明,后面在修正)
Mac 地址一直在变
目的 IP 是一种长远目标,Mac 是下一阶段目标,目的 IP 是路径选择的重要依
据,mac 地址是局域网转发的重要依据
3.端口号
但是这里要思考一个问题:数据传输到主机是目的吗?不是的。
比如说:我用qq给你发信息,目的是让你收到消息。而我们用的qq就是进程,所以:数据传输到主机不是目的,而是手段。到达主机内部,再交给主机内的进程,才是目的。
但是系统中,同时会存在非常多的进程,当数据到达目标主机之后,怎么转发给目标
进程?这就要在网络的背景下,在系统中,标识主机的唯一性。
1.认识端口号:
端口号(port)是传输层协议的内容.
端口号是一个 2 字节 16 位的整数;
端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理;
IP 地址 + 端口号能够标识网络上的某一台主机的某一个进程;
一个端口号只能被一个进程占用.2.端口号范围划分:
0 - 1023: 知名端口号, HTTP, FTP, SSH 等这些广为使用的应用层协议, 他们的
端口号都是固定的.
1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作
系统从这个范围分配的3.理解 "端口号" 和 "进程 ID"
端口号和进程ID都是标识进程唯一性的,为什么还有创建端口号呢?直接套用进程ID不好吗?
进程 ID 属于系统概念,技术上也具有唯一性,确实可以用来标识唯一的一个进程,但是这样做,会让系统进程管理和网络强耦合,实际设计的时候,并没有选择这样做。
4.理解 套接字 socket
IP 地址用来标识互联网中唯一的一台主机,port 用来标识该主机上唯一的一个网络进程
IP+Port 就能表示互联网中唯一的一个进程
所以,通信的时候,本质是两个互联网进程代表人来进行通信,{srcIp,srcPort,dstIp,dstPort}这样的 4 元组就能标识互联网中唯二的两个进程
所以,网络通信的本质,也是进程间通信
我们把 ip+port 叫做套接字 socket
七.传输层的典型代表
TCP协议
TCP协议 的关键特点包括:
- 传输层协议:为应用层提供端到端的可靠通信服务。
- 有连接:数据传输之前需要建立连接,建立过程为三次握手。
- 可靠传输:通过确认、重传、流量控制、序列号等机制保证数据可靠到达。
- 面向字节流:将数据视为连续的字节流进行传输,不关注具体的应用层数据结构。
这些特性使得TCP适合用于对数据完整性和可靠性有较高要求的应用,如文件传输、Web浏览等。
UDP协议
UDP协议 的关键特点包括:
- 传输层协议:负责在源主机和目标主机之间传输数据。
- 无连接:不需要建立连接,传输过程简单、延迟低。
- 不可靠传输:没有确认、重传机制,丢包或乱序的情况可能发生。
- 面向数据报:每个数据包是独立的,彼此之间没有顺序或依赖关系。
UDP 的这些特点使它适合用于对传输速度要求高、对数据完整性要求不高的应用,比如视频流、语音通话和实时游戏等。
八.网络字节序
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?
大端:数据的高字节存储在低地址端,低字节存储在高地址端。
小端:数据的低字节存储在低地址端,高字节存储在高地址端。
对于同样的整数 0x12345678,在小端存储方式下,内存中的存储顺序如下:
地址: | 0x00 | 0x01 | 0x02 | 0x03
数据: | 0x78 | 0x56 | 0x34 | 0x12
发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
TCP/IP 协议规定,网络数据流应采用大端字节序,即低地址高字节.
不管这台主机是大端机还是小端机, 都会按照这个 TCP/IP 规定的网络字节序来发送/接收数据;
如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可;
为使网络程序具有可移植性,使同样的 C 代码在大端和小端计算机上编译后都能正常运
行,可以调用以下库函数做网络字节序和主机字节序的转换。h代表主机字节序 n代表网络字节序 ,l 表示 32 位长整数,s 表示 16 位短整数。
例如 htonl 表示将 32 位的长整数从主机字节序转换为网络字节序,例如将 IP 地址转换后准备发送。