Linux:网络基础

1. 初识协议

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

而网络协议就是计算机网络中通信双方为实现数据交互,预先约定好的数据格式、交互流程、差错处理、寻址方式等一系列通信规则的集合。没有协议,即使两台电脑能够互相通信,但一个说中文、一个说俄语,完全没法听懂对方的数据,这样信息还是无法传递。

协议分层指的是:将整体网络通信规则按功能拆分为多个独立层级,每层只负责固定功能,下层为上层提供通信支撑,上层仅调用下层接口,各层协议相互解耦。

我们来看下面这个例子,在这个例子中,我们的"协议"只有两层:语言层、通信设备层。 但是实际的网络通信协议,设计的会更加复杂,需要分更多的层 但是通过上面的简单例子,我们是能理解,分层可以实现解耦合,让软件维护的成本更低

我们再去这样思考问题:比如现在我要将一份数据从主机A传送到主机B,中间会经过很多设备比如网络、路由器等等,在这个途中会产生什么问题?首先我们必须做到能让数据在两个相邻的设备之间进行传递。然后,我们必须解决主机定位和路径选择的问题,即我的数据从主机A发送出去之后,我该怎么定位到主机B?我在前往主机B的路上该选择怎样的路径?其次,如果数据在传输过程中丢失了怎么办?就像是快递配送一样,路上有可能会出现包裹丢弃,包裹破损的情况,解决方案是什么?最后,当主机B收到这份数据之后,该怎么去处理它?是任由主机B处理,还是会对数据加以一份限制,保护其数据安全?

之所以会出现这些问题,是因为数据从一台主机传送到另一台主机上,物理距离是很长的,因此会出现上面的一系列问题,而为了解决它们,我们必须要客观的统一标准,因此就需要网络通信协议-TCP/IP协议等等。

1.1 OSI 七层模型

OSI(Open Systems Interconnection,开放式系统互联)是 ISO 制定的网络通信标准分层模型,把网络从逻辑上自上而下分为 7 层,每层各司其职、层间解耦,每一层都有相关、相对应的物理设备,比如路由器,交换机。上层调用下层服务,下层为上层提供支撑,相邻层通过接口交互。

设计成七层模型是一种框架性的方法,其最主要的功能使就是帮助不同类型的主机实现数据传输; 它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整。通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。

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

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

TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇。 TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求

物理层

负责光 / 电信号的传递方式。比如现在以太网通用的网线 (双绞线)、早期以太网采用的同轴电缆 (现在主要用于有线电视)、光纤,现在的 wifi 无线网使用电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等。集线器 (Hub) 工作在物理层。

数据链路层

负责设备之间的数据帧的传送和识别。例如网卡设备的驱动、帧同步 (就是说从网线上检测到什么信号算作新帧的开始)、冲突检测 (如果检测到冲突就自动重发)、数据差错校验等工作。有以太网、令牌环网,无线 LAN 等标准。交换机 (Switch) 工作在数据链路层。

网络层

负责地址管理和路由选择。例如在 IP 协议中,通过 IP 地址来标识一台主机,并通过路由表的方式规划出两台主机之间的数据传输的线路 (路由)。路由器 (Router) 工作在网络层。

传输层

负责两台主机之间的数据传输。如传输控制协议 (TCP),能够确保数据可靠的从源主机发送到目标主机。

应用层

负责应用程序间沟通,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等。我们的网络编程主要就是针对应用层。

2. 再识协议

2.1 为什么要有 TCP/IP 协议

首先,即便是单机,你的计算机内部,其实都是存在协议的,比如:其他设备和内存通信,会有内存协议。其他设备和磁盘通信,会有磁盘相关的协议,比如:SATA,IDE,SCSI 等。只不过我们感知不到罢了。而且这些协议都在本地主机各自的硬件中,通信的成本、问题比较少。

远距离跨主机网络通信因为距离差较大,存在设备异构兼容、线路传输易出错、跨网段寻址困难、多应用数据区分等诸多问题,OSI 七层模型落地繁琐难以普及,因此诞生了 TCP/IP 协议簇,它采用精简五层分层架构各司其职,以 IP 协议实现全网主机寻址路由、TCP 完成可靠传输保障,搭配各类配套协议,统一了全网通信标准,解决远距离网络通信各类痛点,让不同厂商、不同系统的设备能够顺畅互联互通,构成了整个互联网通信的基础。

2.2 什么是 TCP/IP 协议

我们先来看一下 TCP/IP 协议与操作系统内核的关系,TCP/IP 协议栈进行了分层部署,其中作为核心的传输层 TCP 协议与网络层 IP 协议直接集成在 Windows、Linux 等操作系统内核当中,数据链路层依靠网卡驱动实现,物理层为网卡硬件,应用层交由上层用户程序实现;用户程序需通过系统调用进入内核调用内置 TCP/IP 协议栈完成网络收发,即便两台主机操作系统整体架构存在差异,只要内核严格实现统一的 TCP、IP 协议标准,就能实现跨系统网络通信,操作系统内核承载了 TCP/IP 最核心的协议逻辑,是整套网络协议正常运转的核心支撑,协议栈整体也需要硬件、驱动、操作系统、上层应用多方协同配合才能完成通信。

那究竟什么是协议呢?我们用这张图更清楚的说明一下:

这张图以结构体通信举例,直观诠释 TCP/IP 协议:主机 A 是 Windows 系统、主机 B 是 Linux 系统,两套操作系统内核、上层软件、硬件驱动完全不同,我在 Windows 里定义一个结构体 int {a,b,c},赋值 10、20、30,如果直接把这块内存二进制丢到网线发给 Linux,Linux 根本读不懂这块二进制,变量顺序、字节排布全对不上,数据直接报废。用专业的话术说就是会因为内存排布、系统解析规则差异无法正常识别,而TCP/IP 就是一套统一、分层的数据封装与解析通信规范,整体分为应用层、传输层、网络层、数据链路层、物理网卡五层协议栈;

TCP/IP 就是一套统一打包、拆快递的标准化流程,拆成五层分工干活:

  1. 应用层:就是你要发的结构体原始数据;
  2. 传输层(TCP):给数据包贴标签,标记这是哪个程序发的、确保对方完整收齐、没丢件;
  3. 网络层(IP):写上收件 IP 地址,确定这条数据包该走哪条路由送到目标主机; 这两层直接写死在系统内核里,Windows 和 Linux 内核必须严格按同一个格式打包、解析,不能自己乱改规则。
  4. 数据链路层(网卡驱动):给数据包加上局域网 MAC 地址,交给网卡;
  5. 物理层(网卡硬件):把二进制信号通过网线发出去。

主机 B 收到数据之后,从底层到上层逐层撕掉报头:先网卡接收→驱动处理→内核拆掉 IP 头部找到本机、拆掉 TCP 头部校验数据完整性,最后把纯净的原始结构体数据交给上层应用。这个过程生动地诠释了:所谓"协议",就是让发送方按照双方公认的"结构体模板"去排列字节,接收方严格按照同一份"模板"去切割和解释字节。只要模板(协议)统一,即便两边的操作系统和硬件天差地别,还原出的结构体也必然分毫不差。

所谓报头,就是网络各层协议附加在业务数据前面的控制信息,不包含用户真正要发送的内容,存放该层处理数据包必须的信息,像链路层报头存放源、目标 MAC,网络层报头存放源、目的 IP,传输层报头存放端口号,发送封装的时候把报头拼在数据头部,接收端读取报头获取处理信息,处理完毕就把报头去掉,将内部数据交给上一层,没有报头网络设备就无法识别、转发和交付数据。

所以,回过头来看协议的朴素理解------"协议就是通信双方都认识的结构化数据类型"------我刚刚描述的整个TCP/IP五层拆包过程,其实就是在解决一个核心矛盾:Windows和Linux内存里的struct {int a,b,c;},是本地私有的数据类型(字节序、对齐方式各不相同),直接扔到网线上就是乱码。而TCP/IP协议栈的作用,就是逐层给这份"私有数据"裹上一层又一层的"公共快递盒"。

传输层的TCP头部、网络层的IP头部,这些头部本身都是被RFC标准严格定义过的结构化数据类型(比如TCP头部前2个字节必须是源端口,IP头部第13-16字节必须是源IP)。这两层头部的格式,是全世界的Windows和Linux内核都必须"认识"且"严格遵守"的公共数据结构。

当原始结构体数据被塞进TCP payload时,它通过网络字节序(大端)这一强制约定,将原本因硬件差异而混乱的二进制排布,重新标准化为一种网络上的通用数据类型。

因此,"朴素理解"是目标(应用层看到纯净的a=10,b=20,c=30),而"TCP/IP分层"是手段。分层协议的本质,就是用一组固定的、分层的公共数据结构(各层头部),去封装和承载那些异构的、不兼容的私有数据结构。只要打包(封装)和拆包(解析)的规矩一模一样,那么对于通信双方的操作系统内核而言,网线上传输的二进制流就不再是乱码,而是一份它们共同认识的结构化数据------这便是"协议"二字最底层的含义。

下面给大家展示一下网络层的IP协议:

cpp 复制代码
struct iphdr {
    #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u8 ihl:4,        // 首部长度(4位),单位是4字节
             version:4;    // IP版本(4位),IPv4为4
    #elif defined (__BIG_ENDIAN_BITFIELD)
        __u8 version:4,
             ihl:4;
    #endif
    __u8 tos;              // 服务类型(8位)
    __be16 tot_len;        // 总长度(16位),包含头部和数据
    __be16 id;             // 标识符(16位),用于分片重组
    __be16 frag_off;       // 分片偏移(13位)和标志(3位)
    __u8 ttl;              // 生存时间(8位),防止数据包无限循环
    __u8 protocol;         // 上层协议(8位),如6代表TCP,17代表UDP[reference:16]
    __sum16 check;         // 头部校验和(16位)
    __be32 saddr;          // 源IP地址(32位)
    __be32 daddr;          // 目的IP地址(32位)
};

这是网络层的"通用数据类型",负责给数据包写上"收件地址"(IP地址),以便在全球网络中路由,这个结构体里,protocol 字段是连接网络层和传输层的"钥匙",它指明了后续数据属于哪种传输层协议。

3. 网络传输基本流程

3.1 局域网通信

我们先来简单认识一下什么是以太网。要理解以太网,我们不妨先把所有复杂的电子信号和协议栈抛到一边,只盯着一个最朴素的物理现实:以太网本质上解决的是"一群紧挨着的主机,如何共用同一根线缆或同一个物理空间,有序地把数据送达给其中某一个特定目标"的问题。

这就好比你走进一间宽敞的大教室,里面坐满了互不相识的学生,这就是一个典型的共享广播域------教室里的空气就是共用的物理信道,任何一个人开口说话,理论上教室里所有其他人都能听到。以太网最初的设计思想就源于此,它把每一台主机都看作教室里的一名学生,而通信过程就是传纸条或喊话。但这里立刻冒出一个核心难题:如果大家随心所欲地同时喊话,声音就会混在一起,谁也听不清;如果所有人都只盯着传纸条,那必须得有一个机制确保纸条不会被错拿。

为了解决这个"有序投递"的问题,以太网在设计之初就确定了两件最根本的事:其一,给教室里的每个学生一个唯一且固定的学号,这就是MAC地址;其二,定下一套大家必须遵守的"发言规则",规定谁在什么时候能开口,话该以什么格式说。

首先,MAC(Media Access Control,介质访问控制)地址 ,也叫物理地址、硬件地址,是烧录在网卡硬件里的唯一标识符,用来在局域网内识别一台网络设备。它的长度是 48 位二进制,通常写成 12 位十六进制,格式示例:00‑1A‑2B‑3C‑4D‑5E 或者 00:1A:2B:3C:4D:5E,其中前 6 位代表 厂商 OUI 编号,代表网卡生产厂家,后 6 位是 厂商分配给这块网卡的唯一编号,保证全球网卡 MAC 不重复。

这就好比每个学生从入学起就带在身上的身份证号,绝不会与同班同学重复。当你想递给张三一张纸条时,你必须在纸条的封面封皮上清清楚楚地写下张三的身份证号,而教室里的规则极其严格:每个人都竖着耳朵听,但每个人只认自己的号,只有张三听到或看到自己的号码时才会把纸条拆开阅读,其余人即便耳朵听到了,也会因为号码不匹配而选择直接忽略。这正是以太网帧头部设计的逻辑,由于MAC地址的存在,使得网卡在硬件层面就能完成第一道精准的过滤,从而避免了CPU被大量无关数据频繁打扰。

比如这张图演示以太网广播通信原理

  1. 主机 A 要给主机 E 发送数据,构造帧:源 MAC 是 MacA,目标 MAC 是 MacE,数据内容 "你好"。

  2. 把这个帧发到以太网局域网,局域网里所有主机(B、C、D、E)都会收到这份帧

  3. 主机 B、C、D 拿到帧后,对比目标 MAC,发现不是自己的 MAC 地址,直接丢弃该报文。

  4. 只有主机 E 发现目的 MAC 和自己 MacE 匹配,接收这份数据,之后再用同样的以太网方式回复主机 A。

这揭示了早期以太网是广播机制,数据包会广播给内网全部设备,设备靠 MAC 地址判断这个包是不是发给自己,不是就扔掉。

以太网中,任何时刻,只允许一台机器向网络中发送数据,如果有多台同时发送,会发生数据干扰,我们称之为数据碰撞 ,因此所有发送数据的主机要进行碰撞检测和碰撞避免。没有交换机的情况下,一个以太网就是一个碰撞域。在局域网通信的过程中,主机对收到的报文确认是否是发给自己的,是通过目标mac地址判定。

下面我们再来搞清楚一些概念,要回答两个问题,局域网和以太网是什么关系,还有其他的局域网通信标准吗?以太网为什么要叫以太网?

首先局域网(LAN)是大类概念,即小范围的本地网络(家庭、办公室)。以太网是局域网里面最主流的一种具体实现技术。这就好比是 局域网 = 水果;以太网 = 苹果。

而局域网标准还有很多,IEEE802 系列定义了多种局域网标准:

  1. 令牌环网 Token‑Ring(802.5) 老 IBM 方案:轮流传递 "令牌",拿到令牌才能发数据,没有冲突。已经淘汰。
  2. 令牌总线 Token‑Bus(802.4) 同轴电缆,总线上传递令牌,工控早期使用,现已淘汰。
  3. FDDI:光纤分布式数据接口,光纤做局域网,双环冗余,早年校园骨干网,淘汰。
  4. WLAN WiFi(802.11)无线局域网,属于局域网,不是以太网。WiFi 也有 MAC 地址,但帧格式和以太网不一样,我们家里 Wi‑Fi 属于局域网,但不是以太网。
  5. 蓝牙(802.15):短距离个人局域网。

不过结局是,以太网打败了令牌环、FDDI,成为有线局域网绝对霸主,现在绝大多数有线局域网,跑的都是以太网。;WiFi 是无线局域网主流。

而以太网这个名字来自物理学历史概念 以太(Ether) 。19 世纪物理学假说:人们假设宇宙充满看不见的介质叫 以太 (aether),认为光、电磁波依靠 "以太" 在空间传播。后来迈克尔逊‑莫雷 实验证明以太不存在。1973 年,发明者梅特卡夫设计早期同轴电缆以太网:共享的同轴电缆就像 "以太",所有计算机的信号都在这一根公共介质上面广播传播,就如同电磁波假想中在以太里传播。于是命名 Ether‑net,翻译为以太网。刚好对应我们上面的图片:早期同轴以太网,所有设备挂在同一条总线上,报文广播给全部主机,就像信号弥漫在 "以太介质" 中。

我们再来看同⼀个网段内的两台主机进行发送消息的过程:

这个过程就是主机 1 的用户数据 "你好" 在发送时从上到下经过应用层、传输层、网络层、数据链路层完成封装,每一层都会给数据加上属于自己的协议报头,封装完成后由网卡转为电信号通过网络传输到主机 2,主机 2 收到数据后执行反向的解封装操作,从下往上逐层剥掉各层报头,最终取出原始数据交给上层应用,模型里的红色箭头代表对等层通信,每一层逻辑上仿佛直接和对端的同一层交互,但真实的数据必须经过层层封装、物理传输再层层解封装才能完成收发。

另外大家还要了解一下协议报头和有效载荷,这张图里,协议报头 是每一层协议在接收上层传来的数据之前,在最前面新增的一段本层控制信息;而交给这一层处理的上层全部内容(上层报头 + 原始用户数据)就叫做这一层的有效载荷 。 以图中例子,原始用户内容是 "你好",到应用层,应用层加上自己的应用层协议报头 ,此时 "你好" 就是应用层的有效载荷;往下交给传输层,传输层拼接上传输层报头,那么 "应用层报头 + 你好" 这整块就变成传输层的有效载荷,其他各个层级都遵循这个相同逻辑。

但这样画图不是很直观,我们可以这样去看:

这不就是我们最熟悉的栈结构吗,在传输数据时,每个协议层都加上自己的报头,这就相当于入栈,而当目标接收信息开始解包的时候,就相当于出栈。因此我们也把 TCP/IP 协议成为协议栈。

3.2 跨网络通信

跨网络通信是指,数据不在同一个局域网内部通信,需要经过路由器转发,从一个网络送到另一个网络。日常生活中我们也经常会进行跨网络通信,比如手机用流量访问网站、家里电脑和外地服务器通信,这些通信方式数据包要经过路由器、网关、多个中间网络设备转发。

再理解跨网络通信之前,我们要先了解一下IP地址和IP协议,IP 协议,也就是网际协议,是 TCP/IP 体系里网络层的核心协议。它负责把数据包从源主机,跨网络路由送到目标主机,定义数据包格式、寻址规则、分片处理,不保证数据一定送达,属于不可靠协议。IP 地址,是 IP 协议给网络设备分配的逻辑编号。用来在跨网络通信时标识发送方和接收方,路由器依靠 IP 地址选择转发路径。 同一个局域网可以有相同 MAC,但 IP 地址不能冲突。 IPv4 是 32 位,IPv6 是 128 位,分别对应两套地址体系。总结就是,MAC 地址管局域网内部转发,IP 地址管跨网络的路由传输。

而我们一般说IP地址时默认指的是 IPv4 ,IPv4 是互联网目前广泛使用的第四版网际协议,作用是给网络中的设备分配地址,实现跨网络的数据路由转发。IPv4 使用 32 位二进制地址,写成点分十进制格式,例如 192.168.1.1。 总地址数量约 43 亿,地址资源已经枯竭,大量场景依靠 NAT 地址转换共用公网 IP。 报头长度可变,配置简单,所有网络设备都全面兼容。

IPv6 是下一代网际协议,用来解决 IPv4 地址不足的问题,完成设备之间的网络寻址。IPv6 采用 128 位二进制地址,使用冒分十六进制书写,例如 2001:db8::1。 地址总量极大,几乎可以给每一台设备分配独立公网 IP。 报头固定长度,简化数据包处理,内置 IPSec 安全支持,广播机制被取消,使用组播。

IPv4 和 IPv6 不能直接互相通信,需要双栈、隧道等技术完成兼容过渡。 IPv4 侧重成熟兼容,IPv6 侧重海量地址与原生安全。

而我们前面提到过MAC地址,说是烧录在网卡硬件里的唯一标识符,用来在局域网内识别一台网络设备的地址。这跟我们的IP地址不是很相似吗,那一台电脑为什么要有两个地址呢?

我们用一个例子来讲解,西游记的故事大家应该都不陌生,唐僧每次到达一个国家的时候,都会说:贫僧从东土大唐而来,前往西天取经。比如唐僧现在来到了狮驼国,他就问狮驼国国王,说国王国王,我们要去西天,下一站应该到哪个国家?国王就说,下一站是比丘国。于是唐僧到达比丘国,又会说,贫僧自东土大唐而来,前往西天取经,刚刚经过狮驼国,来到了这里。因此在唐僧的话中,东土大唐和西天是两个一直不变的地名。而从狮驼国到比丘国,这两个地名会一直改变,下一次就变成了比丘国到灭法国。

而IP地址和MAC地址的关系就像如此,在跨网络传输的过程当中,数据会从起始地址不断传送到目标地址,中途会经历很多其他地方,而IP地址提供长远目标,一直指向目标地址。而MAC地址指向当前或下一站地址,解决的是局域网转发的问题。

最后总结一下,我们跨网络通信的过程大概就是这样一个流程:

本文到此结束,感谢各位读者的阅读,如果有讲解的不到位或者错误的地方,欢迎各位读者批评或指正。

相关推荐
HY小宝F1 小时前
腾讯云 × 树莓派摄像头四周实战学习路线 第 2 周 · 第 14 天 · RTSP 实验 — 学习小结
网络
天行健,君子而铎1 小时前
数据分类分级的范式转换:从规则匹配到模型持续优化规模化前瞻算法
大数据·网络·数据库·安全·分类
云运维笔记1 小时前
免费模拟器ENSP:零成本学网络配置
服务器·网络·智能路由器
Mortalbreeze2 小时前
深入理解 Linux IO 模型(四):多路复用 —— epoll
linux·运维·服务器·网络·tcp/ip
CedarQR2 小时前
LubanCat-2 (RK3568) Debian 下让 H3C Magic USB 无线网卡(AIC8800)联网全记录
linux·网络·单片机·嵌入式硬件·debian·3568·h3c
STQY燊桐启元(深圳)电子科技2 小时前
5G 小基站整机热-EMC 协同设计,ST-XDP 应用实例,DP 用于电 源功率模块
网络·机器人
Cx330❀13 小时前
【Linux网络】网络层协议 IP :从网络层原理到 Linux 内核源码
linux·运维·服务器·网络·tcp/ip·ai·ai编程
FPC工厂——皇榜科技14 小时前
机器人灵巧手线路板:从“握得住”到“摸得准”:一只机械手的柔性神经密码
网络·人工智能·科技·机器人·pcb工艺
Orange_sparkle15 小时前
Pi Agent vs LangGraph:从人机交互、企业 RAG 到持久化工作流的完整选型指南
java·网络·人机交互