第3章 第10.2天
同学们!咱们这次来啃啃网络世界的基石——TCP/IP协议栈。别被那些分层和首部吓到,它本质上就是一套精密分工的“快递规则”,让不同设备(电脑、手机、服务器)能讲同一种“语言”。我会用咱们宿舍联网开黑、抢课、刷视频这些真实场景,配上关键命令和代码片段,保证让你看清数据包在网线里穿梭的每一层“包装”!( •̀ ω •́ )✧
标题:从宿舍开黑到全球互联:TCP/IP协议栈实战拆解与抓包分析指南
一、TCP/IP背景:从封闭小圈子到全球互联
想象一下你们宿舍楼:起初只能用同一种牌子的对讲机(NCP协议)内部喊话。后来想和隔壁女生楼联谊,却发现人家用不同牌子的对讲机,完全听不懂!这就像早期的ARPANET,只能在同构网络通信。
TCP/IP的诞生就是解决这个“鸡同鸭讲”:
1.1980年诞生: 设计目标就是让异构网络(不同硬件、操作系统)能互相通信。想象它制定了一套“国际快递通用包装和运输标准”。
2.1982年成为标准: ARPANET全面采用,奠定了现代互联网的基础。这套标准不是单一协议,而是一个协议族(Protocol Suite),包含:
*HTTP (网页浏览)
*IP (寻址和路由)
*DNS (域名翻译)
*TCP (可靠运输)
*UDP (快速运输)
*ARP (地址查询)
*等等... 它们统称TCP/IP协议族。
3.核心价值:开放性和互操作性。 就像无论你用华为、小米、iPhone,只要遵循蜂窝网络标准,就能打电话上网。
二、TCP/IP四层流水线:层层分工,环环相扣
TCP/IP简化了OSI模型,分为四层。咱们从最底层的“物理搬运”讲到最顶层的“应用服务”。
1. 网络接口层 (链路层/数据链路层) - “本地社区快递员”
职责: 负责在同一个物理网段内(如你的宿舍WiFi、实验室局域网),把数据封装成帧(Frame),通过MAC地址精确投递到相邻设备(如你的电脑到宿舍路由器)。
关键机制:
MAC地址寻址: 每个网卡都有一个全球唯一的物理地址,格式 AA:BB:CC:DD:EE:FF (6字节)。前3字节标识厂商,后3字节设备号。这是设备在局域网内的“门牌号”。*
*帧封装:
// 简化以太网帧结构示意 (关键字段)
+-----------------+-----------------+-------+----------+---------+
| 目标MAC (6字节) | 源MAC (6字节)| 类型|数据| FCS|
| (e.g. Router)| (e.g. Your PC) | (2字节)| (46-1500B)| (4字节) |
+-----------------+-----------------+-------+----------+---------+
// 注释:
// 1. 目标MAC/源MAC:决定帧在本地网段发给谁、谁发的。
// 2. 类型 (Type):标识上一层用什么协议解析数据 (0x0800=IP, 0x0806=ARP)。
// 3. 数据 (Data):携带的上层协议数据包 (通常是IP包)。
// 4. FCS (Frame Check Sequence):帧校验序列,用于检测传输错误 (CRC校验)。
广播(Broadcast): ARP协议查询MAC地址时,会向局域网内所有设备喊话:“谁有IP地址192.168.1.1?告诉我你的MAC!”(目标MAC=FF:FF:FF:FF:FF:FF)。
大学生活案例:
*你的笔记本电脑 (MAC_A) 想通过宿舍路由器 (MAC_R) 上网。访问百度时,电脑需要知道 MAC_R 的地址,于是发起 ARP广播查询:“谁有192.168.1.1(网关IP)?”。路由器 MAC_R 回应:“是我,我的MAC是XX:XX:XX:XX:XX:XX”。电脑把目标MAC设为 MAC_R 发送数据帧。
*交换机 (Switch) 工作在链路层,基于MAC地址表转发帧,避免像老式集线器(Hub**)那样广播泛滥。
*示例命令 (查看MAC和ARP缓存):
# Linux/Mac:查看网卡(如 eth0/wlan0) MAC地址
ip link show eth0# 找 'link/ether' 后的地址
# 或老命令
ifconfig eth0 | grep ether
# Windows:查看网卡MAC地址
ipconfig /all# 找 "物理地址"
# 查看本机ARP缓存表 (记录IP对应的MAC)
arp -a
# 输出示例:192.168.1.1 (网关) 对应的 MAC 地址
2. 互联网络层 (网络层) - “全球邮政系统与导航员”
职责: 实现跨网络、端到端的逻辑寻址和路由。核心任务是:“这个数据包最终要送到哪个网络?下一站该交给哪个路由器?”*
核心协议:
IP协议 (IPv4/v6):
核心功能: 给网络中的设备分配逻辑地址(IP地址)* (如 192.168.1.100),并通过子网掩码 (如 255.255.255.0) 区分网络号和主机号。
*IP数据包结构:
// 简化IPv4数据包结构示意 (关键字段)
+----------+-----------+-----+---------+-----------+--------+---------+
| 版本/IHL | TOS(服务类型)| 总长度| 标识/标志/片偏移 (分片用) | TTL| 协议号 | 首部校验和 |
+----------+-----------+-----+---------+-----------+--------+---------+
|源IP地址 (4字节)|
+---------------------------------------------------------------------+
|目标IP地址 (4字节)|
+---------------------------------------------------------------------+
|数据 (传输层数据包)|
+---------------------------------------------------------------------+
// 注释:
// 1. 源IP/目标IP:数据包的起点和终点逻辑地址(全局定位)。
// 2. TTL (Time To Live):生存时间,每经过一个路由器减1,防止环路导致包永远转圈。
// 3. 协议号 (Protocol):标识传输层用TCP(6)还是UDP(17)解析数据。
// 4. 分片相关字段:当数据包太大,超过链路层MTU限制时,会被分割发送。
ARP协议: 前面讲过,负责将目标IP地址解析为同一局域网内的目标MAC地址。arp -a 查看的就是ARP缓存。
路由协议 (RIP, OSPF, BGP等): 路由器之间交换网络路径信息,动态生成路由表,决定数据包的下一跳去哪。你的电脑也有个简单路由表。
大学生活案例:
*你在宿舍 (192.168.1.100) 访问B站服务器 (180.101.49.12)。你的电脑检查目标IP 180.101.49.12 不在宿舍子网 (192.168.1.0/24),于是根据默认网关* (192.168.1.1) 配置,把数据包目标MAC设为路由器MAC发送。
*学校在不同校区可能有不同子网 (如 10.1.0.0/16, 10.2.0.0/16),核心路由器运行OSPF等协议学习路径,确保跨校区访问畅通。
*示例命令 (查看路由表与追踪):
# 查看本机路由表 - 决定数据包去向
ip route show
# 或 Windows: route print
# 关键行示例:default via 192.168.1.1 dev eth0# 默认网关
# 追踪到 www.baidu.com 的网络路径
traceroute www.baidu.com# Linux/Mac
tracert www.baidu.com# Windows
# 显示数据包经过的每一跳路由器IP (网络层路由过程可视化)
3. 传输层 - “可靠信使 vs 快递小哥”
职责: 提供端到端* (你的电脑进程 <-> 服务器进程) 的数据传输服务。核心是端口号 (Port),它标识了主机上的具体应用程序。
两大协议对比:
TCP (传输控制协议) - “可靠的信使”:
特点: 面向连接 (需要先握手建立连接)、可靠交付* (确认、重传、排序、流量控制、拥塞控制)、全双工。
适用场景: 要求数据绝对完整、顺序正确*的场景。如:网页浏览 (HTTP/HTTPS)、文件传输 (FTP/SFTP)、邮件发送 (SMTP)、远程桌面 (RDP)、数据库访问。
*TCP首部关键字段:
// 简化TCP首部示意
+-----------+-----------+--------------------+---------------------+
| 源端口| 目标端口| 序列号 (SEQ)| 确认号 (ACK)|
+-----------+-----------+--------------------+---------------------+
| 数据偏移等 | 控制标志| 窗口大小 (Win)| 校验和| 紧急指针 |
|| (SYN,ACK, | (流量控制关键)|||
|| FIN,RST...)||||
+-----------+-----------+--------------------+---------------------+
// 注释:
// 1. 源端口/目标端口:标识通信双方的应用进程。
// 2. 序列号(SEQ)/确认号(ACK):实现可靠传输的核心。SEQ是本端发送数据的编号,ACK是期望收到的对方数据的下一个编号。
// 3. 控制标志:
//- SYN (Synchronize):发起连接请求。
//- ACK (Acknowledgment):确认有效。
//- FIN (Finish):请求关闭连接。
//- RST (Reset):重置连接(异常断开)。
// 4. 窗口大小(Window):接收方告知发送方自己还能接收多少数据(流量控制)。
*经典流程:TCP三次握手建立连接
客户端 (你刷B站)服务器 (B站服务器)
| --- SYN=1, SEQ=X ---> |# 客户端:我想连接,我的初始序号是X
| <-- SYN=1, ACK=1,|# 服务器:同意连接!我的初始序号是Y,确认收到你的X (ACK=X+1)
|ACK=X+1, SEQ=Y -->|
| --- ACK=1, ACK=Y+1 -->|# 客户端:确认收到你的Y (ACK=Y+1)
# 注释:SYN包消耗一个序号。ACK=X+1 表示期望收到序号为X+1的数据。
UDP (用户数据报协议) - “快速的快递小哥”:
特点: 无连接 (直接发)、不可靠** (不保证送达、不保证顺序、不重传)、开销小 (首部仅8字节)、速度快。
适用场景: 对实时性要求高*,能容忍少量丢包的场景。如:在线视频/语音通话、DNS查询、多人网游、广播/组播。
*UDP首部:
// UDP首部非常简单
+-----------+-----------+-------------+-------------+
| 源端口| 目标端口| 数据报长度| 校验和|
+-----------+-----------+-------------+-------------+
// 注释:没有序列号、确认号、复杂的控制标志。长度字段包含首部和数据总长度。
*大学生活案例:
*TCP场景:
*用浏览器访问教务系统抢课 (TCP 80/443),一个字节都不能错!
*用SSH (TCP 22) 登录实验室Linux服务器操作。
*用FTP (TCP 21) 客户端上传实验报告到服务器。
*UDP场景:
*和室友开黑打《英雄联盟》/《CS:GO》,角色位置实时更新用UDP,丢几个包影响不大,但延迟低最重要。
*宿舍电脑用DNS (UDP 53) 查询 www.bilibili.com 的IP (查询包小,响应快)。
*看B站直播,视频流通常用UDP传输优化速度。
*示例命令 (查看端口连接):
# Linux/Mac:查看TCP/UDP连接及监听端口和进程 (推荐 ss)
ss -tulnp
# 输出示例:
# Netid StateRecv-Q Send-QLocal Address:Port Peer Address:Port Process
# tcpLISTEN 0128*:22*:*users:(("sshd",pid=123,fd=3))
# tcpESTAB00192.168.1.100:54321104.16.xx.xx:443 users:(("chrome",pid=456,fd=123))
# udpUNCONN 00192.168.1.100:68192.168.1.1:67users:(("dhclient",pid=789,fd=6))
# Windows:查看TCP/UDP连接及监听端口
netstat -ano
# -a 所有连接和监听, -n 数字显示地址端口, -o 显示进程PID (在任务管理器查PID对应进程)
4. 应用层 - “终极服务提供者”
职责: 直接面向用户和应用程序。定义了数据交换的格式和规则,以及应用进程如何利用下层(传输层)提供的服务进行通信。
关键特点:
协议众多: HTTP(S) (网页), FTP/SFTP (文件传输), SMTP/POP3/IMAP (邮件), SSH (安全远程登录), DNS (域名解析), DHCP (动态IP分配) 等。
数据格式协商: 应用层协议通常包含字段明确告知对方数据的类型和格式。
*HTTP示例: 浏览器请求头 Accept: text/html,application/xhtml+xml,... 告诉服务器它能接收哪些类型的数据。服务器响应头 Content-Type: text/html; charset=UTF-8 告诉浏览器返回的是HTML文本,编码是UTF-8。
*FTP示例: 使用 ASCII 或 Binary 模式传输文本或二进制文件。
*大学生活案例:
*用Chrome/Firefox访问学校官网 (HTTP/HTTPS)。
*用Outlook/Foxmail收发学校邮箱邮件 (SMTP发信, POP3/IMAP收信)。
*用WinSCP/FileZilla (SFTP over SSH) 传输实验代码到服务器。
*电脑开机自动获取宿舍路由器分配的IP地址 (DHCP)。
*输入 ssh user@labserver.school.edu.cn (SSH) 登录实验室机器。
*示例代码 (Python socket 创建TCP客户端 - 模拟HTTP GET):
import socket
# 1. 创建TCP套接字 (AF_INET=IPv4, SOCK_STREAM=TCP)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 连接服务器 (应用层指定目标:域名和HTTP端口80)
server_address = ('www.example.com', 80)# 应用层目标
client_socket.connect(server_address)# 传输层建立TCP连接
# 3. 构造HTTP GET请求 (应用层数据格式)
request = b"GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: close\r\n\r\n"
# 4. 发送请求 (通过已建立的TCP连接)
client_socket.sendall(request)
# 5. 接收响应数据
response = b""
while True:
data = client_socket.recv(1024)
if not data:
break
response += data
# 6. 关闭连接
client_socket.close()
# 7. 打印响应 (包含HTTP头和网页HTML)
print(response.decode('utf-8'))
四、数据封装与解封装:数据的“包装”与“拆包”之旅
想象你要寄一本《计算机网络》教材给外校同学:
1.发送端 (封装 - Packaging):
*应用层: 你写个便条 “To: 张三, 书已寄出” (应用层数据)。
*传输层: 把便条放进小信封,写上 源端口(你宿舍号) 和 目标端口(张三宿舍号) (添加TCP/UDP头)。
*网络层: 把小信封放进大快递袋,写上 源IP(你学校地址) 和 目标IP(张三学校地址) (添加IP头)。
*链路层: 把快递袋装进快递盒,贴上 源MAC(你宿舍楼快递点地址) 和 目标MAC(你学校大门口收发室地址) (添加以太网头和FCS尾)。
*物理层: 快递盒变成货车上的货物 (比特流),沿着公路(网线/光纤/无线)出发。
2.接收端 (解封装 - Unpackaging):
*物理层: 货车开到张三学校大门 (物理信号到达接收网卡)。
*链路层: 收发室拆开快递盒 (去掉以太网头和尾),检查FCS确认盒子没损坏。根据目标MAC确认是寄到这里。
*网络层: 收发室拆开大快递袋 (去掉IP头),根据目标IP地址知道要送去张三所在的宿舍楼。
*传输层: 宿舍楼管理员拆开小信封 (去掉TCP/UDP头),根据目标端口号送到张三的宿舍。
*应用层: 张三拿到便条 (应用层数据),知道了书已寄出。
关键点: 数据在发送端自上而下封装,每层添加本层的控制信息(首部);在接收端自下而上解封装,每层读取并剥离本层首部,将数据交给上层协议处理。
五、抓包实战:用Wireshark透视网络通信
理解了理论,最好的验证就是抓包!我们以最流行的 Wireshark 为例。
课堂实践步骤:理解访问网页全过程
1.安装Wireshark:
*官网下载安装包:https://www.wireshark.org/
*安装时注意勾选安装 Npcap (Windows) 或 libpcap (Linux/Mac) 驱动。
2.监听上网网卡:
*启动 Wireshark。
*在接口列表中选择你正在用来上网的网卡 (通常是 Wi-Fi 或有线网卡 Ethernet)。名字后面有流量波动条的通常就是。
*点击 Start 开始捕获。
3.访问网站并过滤:
*打开浏览器,访问一个 HTTP 网站 (非HTTPS,方便查看明文内容),例如 http://example.com。
*回到 Wireshark,在过滤栏输入 http (小写),按回车。这将只显示应用层协议是HTTP的数据包。
4.分析关键数据包 - 透视分层:
查找 TCP 三次握手: 在过滤栏输入 tcp.port == 80 && tcp.flags.syn == 1。你应该能看到3个包:[SYN], [SYN, ACK], [ACK]。点开它们看传输层协议(TCP)的首部字段* (源端口、目标端口、SYN/ACK标志、序列号)。
查看 HTTP 请求: 找到类型是 HTTP 的 GET 请求包。在Packet Details面板展开 Hypertext Transfer Protocol (应用层):*
*查看 GET / HTTP/1.1。
*查看 Host: example.com。
查看 Accept 等请求头。
查看 HTTP 响应: 找到类型是 HTTP 的响应包 (通常在请求包之后)。展开应用层:
*查看 HTTP/1.1 200 OK。
*查看 Content-Type: text/html。
查看实际的HTML数据 (可能显示在底部或 Line-based text data 中)。
传输层视角: 选择HTTP请求或响应包。展开 Transmission Control Protocol (传输层):
*查看源端口 (通常是随机高位端口) 和目标端口 (80)。
查看序列号、确认号、窗口大小、标志位。
网络层视角: 选择同一个包。展开 Internet Protocol Version 4 (网络层):
*查看源IP (你的IP) 和目标IP (example.com的IP)。
*查看TTL (一般是64或128)。
查看协议号 (TCP是6)。
链路层视角: 选择同一个包。展开 Ethernet II (链路层):
*查看目标MAC (应该是你网关路由器的MAC)。
*查看源MAC (你的电脑网卡MAC)。
*查看类型 (IPv4是 0x0800)。
5.查找 TCP 四次挥手: (可选) 访问完网页后,在过滤栏输入 tcp.port == 80 && tcp.flags.fin == 1。通常能看到4个包:[FIN, ACK], [ACK], [FIN, ACK], [ACK]。分析FIN和ACK标志位的变化。
核心收获: 通过Wireshark,你可以直观地看到TCP/IP协议栈各层是如何协作的,数据是如何被一层层封装和解封装的。这才是理解网络协议最有效的方式!(๑•̀ㅂ•́)و✧
学长最后的嘱咐:
TCP/IP不是空中楼阁。理解了这四层分工(链路层定邻居、网络层定路线、传输层定可靠/快速、应用层定格式),下次遇到“能上QQ不能开网页”(可能是DNS端口53被阻或HTTP代理问题)、“游戏延迟高”(可能UDP路径问题)、“ssh连不上服务器”(TCP 22端口是否开放)这些经典问题时,你就能按协议栈分层思路一步步排查了!动手抓包试试吧,眼见为实!
感谢浏览和学习,作者:鱼油YOU,转载请注明原文链接:https://www.cnblogs.com/OmegaYOU3/p/19020782,或者可以➕主播WX:OmegaAnimeman_desu;QQ:3819054512
浙公网安备 33010602011771号