本文目标: 读完这篇文章,你将不再靠“感觉”理解网络,而是能用协议栈的视角,清晰回答“数据到底怎么走”的每一个细节。我们会从最底层的电信号,一路拆解到浏览器里的HTTP报文,顺带把内核态和用户态的边界也一并讲透。

 作者介绍

哈喽,我是 CodeStats

一个在底层技术上“考古”了四年的硬核爱好者,也是 WWAIC(全周项目AI编程) 范式的提出者和实践者。我曾手写过一个完整的 Java Web 框架(从 IoC 容器到嵌入式 Tomcat,代码全开源),也喜欢用通俗的语言拆解 CPU、JVM、操作系统的运行本质。

我一直相信,计算机科学没有魔法。所有看似神奇的效果——无论是 java -jar 一键启动,还是多线程自动切换——底层都是简单的规则层层组合

网络也不例外。今天,我们就从最底层的 IP 报文 出发,一路拆解到常用的应用层命令,把整个通信体系彻底“扒干净”。

🎯 通过本文,你将获得什么?

  • ✅ 掌握 TCP/IP 协议栈 的分层逻辑,以及每一层到底“干脏活”的细节

  • ✅ 彻底搞懂 两台电脑通信 的全过程(从敲下回车到收到响应,精确到每个字节的封装)

  • ✅ 弄清楚 ping 和 traceroute 背后完全不同的工作原理,不再混为一谈

  • ✅ 理解为什么 telnet 能测端口,以及它为什么既是“服务”又是“工具”

  • ✅ 了解操作系统默认携带的协议和服务,不再对“系统自带命令”感到陌生

  • ✅ 区分 scpcurlwget 三个极易混淆的命令,根据场景选对工具

  • ✅ 彻底分清 内核态与用户态 的边界——知道哪些是系统写死的,哪些是我们后装的

📑 提问目录

序号 问题
两台电脑是如何完成通信的?
ping 和 traceroute 命令有何区别?
telnet 是如何实现监测端口的?为什么说 telnet 是服务?
操作系统默认会带哪些服务和协议实现?
scpcurl 和 wget 有何区别?
这些协议和工具,到底是内核态执行还是用户态新增?

① 两台电脑是如何完成通信的?

这个问题是整个网络体系的基石。要回答它,必须从TCP/IP协议栈的分层模型说起。网络上传输的数据就像一件包裹,每经过一层就套上一个“信封”,到达目的地后再逐层拆开。

1.1 协议栈:网络通信的“分层哲学”

TCP/IP协议栈采用分层解耦的设计,将复杂的网络通信拆解为独立层次。最经典的是四层模型

层级 名称 核心职责 核心协议/概念
4 应用层 为用户提供网络服务接口 HTTP、DNS、SSH、Telnet
3 传输层 端到端的可靠(TCP)或不可靠(UDP)传输 TCP、UDP
2 网络层 寻址与路由转发 IP、ICMP、ARP
1 网络接口层 物理介质上的数据帧传输,MAC寻址 以太网、Wi-Fi

1.2 一次完整通信:从敲下回车到收到响应

假设电脑A(IP: 192.168.1.10,MAC: AA:AA:AA:AA:AA:01)要访问电脑B(IP: 203.0.113.5)上的Web服务。电脑B在同一企业内网但跨网段,需要通过路由器转发。

第一步:应用层——发起请求(原始数据)

用户在浏览器输入 http://203.0.113.5/index.html,浏览器构造一个 HTTP请求报文,这串文本就是待传输的原始数据。

第二步:传输层——TCP三次握手 + 数据分段

HTTP报文被交给传输层。由于HTTP使用 TCP协议,通信前必须先建立连接(三次握手),确保双方都在线:

  1. 第一次握手(SYN):电脑A → 电脑B,发送 SYN=1, Seq=x(请求建立连接)

  2. 第二次握手(SYN-ACK):电脑B → 电脑A,回复 SYN=1, ACK=x+1, Seq=y(同意建立)

  3. 第三次握手(ACK):电脑A → 电脑B,发送 ACK=y+1(确认,连接正式建立)

TCP是面向连接的、可靠的传输协议。它通过三次握手建立连接,通过序列号保证数据有序,通过校验和保证不丢失。

连接建立后,TCP将HTTP报文分段(Segmentation),并为每段加上 TCP首部(20~60字节),包含关键字段:

  • 源端口(随机,如 52341)

  • 目标端口(80,标识Web服务)

  • 序列号(保证有序到达)

  • 校验和(检查数据是否损坏)

第三步:网络层——封装IP报文(逻辑寻址)

TCP段被交给网络层的 IP协议。IP为其加上 IP首部(20~60字节),包含:

  • 源IP地址192.168.1.10

  • 目标IP地址203.0.113.5

  • TTL(生存时间):初始设为64,每跳减1,防止死循环

IP的主要作用就是在复杂的网络环境中将数据包发给最终的目标地址,它只关心“终点在哪里”,不关心“下一跳是谁的MAC”。

第四步:网络接口层——封装成帧(物理寻址)

IP数据报被交给数据链路层。此时,电脑A需要知道“下一跳”是谁。它查看目标IP 203.0.113.5,发现不在自己网段(192.168.1.0/24),于是决定将数据包发给默认网关(假设IP是 192.168.1.1)。

关键动作:ARP请求
电脑A发出ARP广播:“谁的IP是 192.168.1.1?请告诉我你的MAC地址。”
网关回应:“我的MAC是 GG:GG:GG:GG:GG:01。”
电脑A将网关IP与MAC的映射存入ARP缓存表

封装帧
电脑A加上 帧首部(14字节),包含:

  • 源MAC地址AA:AA:AA:AA:AA:01(电脑A)

  • 目标MAC地址GG:GG:GG:GG:GG:01(网关,即下一跳设备)

在以太网中,数据帧的传递依赖MAC地址,而IP地址只是逻辑终点。每一跳的转发,目标MAC地址都会被重写

第五步:物理传输——比特流上路

帧被转换成电信号/光信号,通过网线/光纤发送到网关(路由器)。

第六步:逐跳转发(路由器的工作)

网关路由器收到数据帧:

  1. 检查帧:剥掉帧头,查看目标MAC是否是自己的(GG:GG:GG:GG:GG:01),是则收下。

  2. 查看IP:查看目标IP 203.0.113.5

  3. 查路由表:路由器查自己的路由表,发现去往 203.0.113.0/24 网段需要从 WAN口 发出,下一跳是 100.100.100.2(运营商路由器)。

  4. 重封装帧:路由器通过ARP获取下一跳 100.100.100.2 的MAC(假设是 OP:OP:OP:OP:OP:01),重新封装帧:

    • 源MAC:改为路由器的WAN口MAC

    • 目标MAC:改为 OP:OP:OP:OP:OP:01

    • 源IP与目标IP保持不变192.168.1.10 → 203.0.113.5

数据包就这样一跳一跳,每跳都重写MAC,直到到达目标电脑B所在的网关,再由该网关通过ARP找到电脑B的MAC,完成最终交付。

第七步:到达目标 + 逐层解封装

数据包到达电脑B后,逆向执行上述过程(网络接口层 → 剥帧,网络层 → 剥IP首部确认IP是自己,传输层 → TCP重组,应用层 → HTTP解析请求)。电脑B返回响应,走同样的路逆向回去——一次完整的网络通信就此完成


② ping 和 traceroute 命令有何区别?

这两个命令都是网络排查的哼哈二将,但设计目标、工作原理截然不同

2.1 核心区别一览

特性 ping traceroute
工具定位 连通性验证工具 路径追踪与跳点定位工具
核心目标 测试目标是否可达、时延与丢包率 追踪数据包的完整路由路径
依赖协议 ICMP(Echo) ICMP(超时)+ UDP(Linux)或 ICMP(Windows)
核心机制 发送ICMP Echo请求,等待Echo应答 利用IP首部的 TTL(生存时间) 字段逐跳探测
输出结果 时延(ms)、丢包率(%)、TTL值 每一跳的路由器IP及对应时延

2.2 ping 的原理

ping 只利用 ICMP回显请求(Type 8) 和 ICMP回显应答(Type 0) 两种报文。

工作流程
本机发送Echo Request → 目标主机回复Echo Reply。本机根据往返时间(RTT)计算时延。

ping服务器在内核中处理ICMP,不经过传输层(不用TCP/UDP),所以它测的是“IP层通不通”,而不是“某个端口开没开”。

2.3 traceroute 的原理

traceroute 的灵魂是 TTL(Time To Live)

工作流程

  1. 发送第一个UDP包(或ICMP包),TTL=1 → 经过第一台路由器时TTL减为0 → 路由器丢弃包并返回 ICMP超时报文(Type 11) → 获取第一跳IP。

  2. 发送第二个包,TTL=2 → 获取第二跳。

  3. 以此类推,直到TTL足够到达目标主机。目标主机返回 ICMP端口不可达(因为traceroute通常故意发往一个高不可达端口)→ 探测结束。

2.4 ⚠️ 重要结论

Ping通 ≠ 业务通。Ping通只代表ICMP协议可达,但目标主机的防火墙可能封禁了80端口或22端口。业务通必须基于应用层协议+特定TCP端口验证。


③ telnet 是如何实现监测端口的?为什么说 telnet 是服务?

3.1 telnet 的“双重身份”

很多人对telnet的认知是混乱的,因为它确实具有双重身份

  • 身份一(协议/服务):它是 TELecommunication NETwork 协议,用于远程终端登录,监听端口 23。作为服务端,它是一个长期运行的守护进程(如 telnetd)。

  • 身份二(客户端工具):我们命令行敲的 telnet 命令,是一个通用的TCP客户端

3.2 telnet 监测端口的原理

telnet 底层完全依赖TCP协议。执行 telnet [IP] [端口] 时:

  1. telnet客户端向目标IP:端口发起TCP三次握手(SYN → SYN-ACK → ACK)。

  2. 握手成功 → 命令行显示 Connected to xxx → 端口开放

  3. 握手失败/超时 → 报错 Connection refused 或 Connection timed out → 端口未开放或防火墙拦截

这也是为什么telnet常用于测试TCP端口——它本质上是利用操作系统内核的TCP连接能力,验证端口是否在监听。

3.3 为什么说它是“服务”?

因为历史上它遵循 C/S架构

  • Telnet客户端telnet 命令。

  • Telnet服务端telnetd 守护进程,监听23端口,接收客户端输入并执行shell命令。

当我们用 telnet 80 测试Web端口时,并没有开启telnet服务端,我们只是借用了客户端的TCP连接能力。如今telnet远程登录已被 SSH(加密) 淘汰,但它的“端口探测”功能依然好用。


④ 操作系统默认会带哪些服务和协议实现?

4.1 内置核心协议栈(内核态)

所有现代操作系统(Windows、Linux、macOS)内置完整的 TCP/IP协议栈

协议 层级 作用
IP 网络层 无连接、不可靠的尽力交付,负责跨网络寻址
ICMP 网络层 差错报告与控制(ping、traceroute的基础)
ARP 网络层/链路层 将IP地址解析为MAC地址(局域网通信必备)
TCP 传输层 面向连接、可靠传输(HTTP/SSH/SMTP的底层)
UDP 传输层 无连接、高效传输(DNS/DHCP/视频流的底层)

4.2 用户态默认系统服务

服务 协议/端口 作用
DNS Client UDP/TCP 53 域名解析缓存服务,将域名转为IP
DHCP Client UDP 67/68 自动从路由器获取IP地址、子网掩码、网关
mDNS / NetBIOS UDP 5353 / 137-138 局域网内设备发现(如AirDrop、网络邻居)

4.3 默认携带的命令行工具

工具 定位 是否默认安装
ping ICMP连通性测试 ✅ 全平台
tracert / traceroute 路由路径追踪 ✅ 全平台
telnet TCP端口测试(客户端) ⚠️ Windows需手动启用(控制面板-功能),Linux默认有
nslookup / dig DNS查询工具 ✅ Windows有nslookup,Linux有dig
ssh / scp 安全远程连接/文件传输 ✅ Linux/macOS默认有,Windows需安装OpenSSH组件
curl / wget HTTP交互与下载 ⚠️ Windows10+内置curl,Linux通常自带curlwget

⑤ scpcurl 和 wget 有何区别?

这三个命令经常被混用,但设计的原点完全不同

5.1 核心区别一览

特性 scp wget curl
核心定位 安全文件传输(复制) 文件下载工具 多协议数据交互(瑞士军刀)
底层协议 SSH(端口22,加密隧道) HTTP / HTTPS / FTP 20+种:HTTP/HTTPS/FTP/SFTP/SCP/POP3等
主要用途 主机间复制文件 从网络下载文件到本地 API交互、上传下载、网页抓取、调试
断点续传 ❌ 不支持 ✅ 支持(-c ✅ 支持(-C -
上传能力 ✅ 直接支持(本地→远程) ❌ 不支持上传(仅下载) ✅ 支持(-T / -F POST上传)
输出详细度 仅进度条 下载进度及基本信息 可输出响应头、Cookie、详细Debug信息
适用人群 运维、系统管理员 普通用户、脚本下载 开发者、API测试工程师

5.2 场景选型指南

  • 场景A:两台Linux服务器之间传文件(小文件) → 用 scp

    bash

    scp -P 2222 /local/file.txt root@192.168.1.100:/remote/
  • 场景B:从互联网下载一个安装包 → 用 wget,简单直接,支持断点续传。

    bash

    wget -c https://example.com/large.iso
  • 场景C:调试RESTful API,发送JSON数据 → 用 curl,灵活处理Header、请求体、超时设置。

    bash

    curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' https://api.example.com/v1/data
  • 场景D:单纯爬取网页源码做分析 → curl 配合 -L 跟随重定向,输出到stdout便于管道处理。


⑥ 这些协议和工具,到底是内核态执行还是用户态新增?

这个问题切中了操作系统的核心边界。明确答案:协议栈跑在内核态;命令工具跑在用户态。

它们之间靠 系统调用(System Call) 来通信。

6.1 哪些跑在“内核态”?(操作系统内核自带,不可新增)

内核态拥有访问硬件(网卡、内存)的最高权限。以下逻辑永远运行在内核中,你无法通过安装软件来替换它们:

  • IP协议:负责寻址和路由转发。

  • ICMP协议:处理 ping 和 traceroute 底层的差错报文。

  • ARP协议:负责IP到MAC的地址解析(局域网通信的基石)。

  • TCP/UDP协议:管理端口监听、三次握手、滑动窗口、重传计时器等复杂状态机。

底层真相:当你打开浏览器访问网页时,你的代码(用户态)并不直接操作网卡。而是通过调用内核提供的 Socket API(套接字接口),把数据交给内核中的TCP/IP栈,由内核负责把数据切成报文、加上校验和、驱动网卡发出去。

6.2 哪些跑在“用户态”?(我们敲的命令,可新增)

你提到的所有命令工具,本质上都是存储在硬盘上的二进制可执行文件。当你敲下回车时,操作系统会为它们创建一个进程,它们运行在用户态,没有任何权限直接触碰网卡。

  • ping / traceroute:虽然是用户态进程,但它们需要调用内核的原始套接字(Raw Socket),因为ICMP报文只能由内核生成。它们是“借内核的手”来发包。

  • telnet / scp / curl / wget:纯用户态应用。它们只是调用了标准的 connect()send()recv() 等系统调用,将数据丢给内核的TCP协议栈,由内核完成真正的收发。

6.3 关于“新增”(用户态新增,而非内核态)

这是一个极易混淆的点:

  • 内核态的协议无法“新增”:你不会去给Linux内核“安装”一个TCP/IP模块,因为它是内核源码编译时就写死的核心组件。

  • 用户态的工具需要“新增”:如果系统没有 curl 或 wget,你需要用包管理器(如 apt install curl)去安装。这个操作是将二进制文件写入 /usr/bin/ 目录,属于用户态新增绝不会动内核代码

唯一的例外(内核模块):内核虽然固定,但可以通过 modprobe 动态加载内核模块(LKM)。比如 iptables 的过滤模块、特殊的网络过滤驱动,这些属于“内核态的热插拔新增”。但你所列的这些标准协议和工具,均不在此列。

6.4 为什么内核态不能乱动?(安全与稳定)

如果允许用户随意“新增”或修改内核协议栈,那么一个进程崩溃就会导致整个操作系统蓝屏/死机。
设计铁律

  • 内核态只负责“干活”(发送比特流、管理定时器)。

  • 用户态只负责“提需求”(我要访问百度、我要下载文件)。

📊 最终速查表

组件名称 运行态 是否随系统自带 可否用户态新增/安装
TCP/IP 协议栈 内核态 ✅ 固写在内核 ❌ 绝不可新增
ICMP/ARP 协议 内核态 ✅ 固写在内核 ❌ 绝不可新增
ping / traceroute 用户态(依赖Raw Socket) ✅ 默认自带 ⚠️ 部分极简系统需安装 iputils-ping
telnet 客户端 用户态 ⚠️ Windows需启用,Linux通常自带 ✅ 需要时可新增
curl / wget 用户态 ⚠️ 新版Windows自带curl,Linux通常自带 ✅ 若无则需新增
scp / ssh 用户态(依赖OpenSSL) ⚠️ 需安装 openssh-client ✅ 若无则需新增

一句话概括:内核是“高速铁路的钢轨和调度系统”,工具是“跑在这条铁路上的各类列车”。你可以随时增购(安装)新列车,但你绝不能在运行中擅自改变钢轨的铺设。

📝 全文总结

从最底层的电信号到顶层的浏览器页面,网络通信就是一场层层封装、逐跳转发、层层解封的接力赛。

  • ① 通信本质:应用数据 → TCP分段(端口+可靠)→ IP寻址(逻辑终点)→ MAC逐跳(物理下一跳)。

  • ② Ping vs Traceroute:Ping测“通不通”(ICMP响应),Traceroute测“怎么走”(TTL耗尽)。

  • ③ Telnet测端口:借TCP三次握手验证端口状态,它本身是一个被SSH淘汰但保留了探测功用的C/S服务。

  • ④ 操作系统默认:内置TCP/IP栈、ICMP、ARP,以及ping/tracert/telnet/nslookup等工具,开箱即用。

  • ⑤ SCP vs Wget vs Curl:SCP传文件(SSH加密),Wget纯下载(简单专注),Curl通吃API(多协议全能)。

  • ⑥ 内核态 vs 用户态:IP/TCP/ARP等协议固化在内核,不可新增;curl/scp等工具运行在用户态,按需安装。

记住这句话:IP决定终点,MAC决定下一跳,端口决定应用,协议决定规则,内核执行硬逻辑,用户态执行软需求。


如果这篇文章帮你撕开了网络通信的黑盒,欢迎点赞、收藏、转发! 有任何疑问或者想深究的底层细节(比如TCP的滑动窗口、HTTPS的TLS握手),欢迎在评论区留言,我们一起在底层“考古”。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐