简介:这份PDF资料面向准备技术面试的开发者与计算机专业学生,系统梳理计算机网络核心考点,帮助读者在有限时间内建立完整的知识框架并应对面试追问。内容围绕网络模型与协议展开,涵盖OSI七层参考模型与TCP/IP四层模型的对比、TCP/IP协议族构成,以及TCP三次握手、四次挥手、状态机、TIME_WAIT、超时重传与快速重传、流量控制和拥塞控制等高频问题,同时涉及IPv4与IPv6、ICMP、ARP、RARP、IGMP等网络层协议,并配有TCP Header结构与协议栈报文格式示例。资源包共1个PDF文件,约2.08MB,结构按章节递进,便于按模块查阅与复习。目前已有969人学习,适合需要快速回顾网络基础、查漏补缺或准备校招社招面试的读者使用。
1. 计算机网络基础知识:从一次“连接超时”说起
线上服务突然报connect timeout,你登录机器ping网关通、telnet端口不通,抓包看到 SYN 发出去没有 SYN-ACK 回来。这时候如果脑子里没有一张分层图,排查就会变成玄学——一会儿怀疑防火墙,一会儿怀疑网卡,一会儿怀疑对端进程没起。计算机网络基础知识真正值钱的地方,不是背出 OSI 七层模型的名字,而是当数据包在某一层出问题时,你能立刻定位到该看哪一层的状态。这篇笔记面向需要把网络调通、把协议讲明白的开发和运维:从 OSI 与 TCP/IP 四层模型的对应关系讲起,落到 TCP 三次握手、UDP 打流、抓包验证的具体命令,最后给出几条我踩过的坑。读完你应该能独立完成一次端到端的连通性排查,并知道每个参数为什么这么设。
2. OSI 七层与 TCP/IP 四层:分层到底怎么对应
2.1 两张模型图的映射关系与各自用途
OSI 七层模型是 ISO 提出的参考模型,自上而下是应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。TCP/IP 四层模型是工程实践中真正落地的模型,自上而下是应用层、传输层、网络层、网络接口层。两者的对应关系是排查问题的第一张地图:
| OSI 七层 | TCP/IP 四层 | 典型协议 | 排查时看什么 |
|---|---|---|---|
| 应用层 / 表示层 / 会话层 | 应用层 | HTTP、DNS、SSH、Modbus TCP | 进程是否监听、应用日志、报文内容 |
| 传输层 | 传输层 | TCP、UDP | 端口状态、握手、重传、丢包 |
| 网络层 | 网络层 | IP、ICMP、ARP(部分实现归此) | 路由、ping、traceroute、MTU |
| 数据链路层 / 物理层 | 网络接口层 | Ethernet、Wi-Fi、PPP | 网卡状态、ethtool、链路灯、CRC 错误 |
为什么要有两张图?OSI 把表示层和会话层单独拆出来,是为了在协议设计时把“数据格式转换”和“会话管理”讲清楚;TCP/IP 把它们合并进应用层,是因为实际协议栈里这两件事通常由应用自己处理。做网络编程时你面对的是 TCP/IP 四层,但理解加密、序列化、长连接保活这些概念时,OSI 的细分更好用。常见做法是:排障用 TCP/IP 四层,讲原理用 OSI 七层。
2.2 数据在四层模型中的封装与解封装过程
一次 HTTP 请求从应用到网线,数据会逐层加头。应用层生成 HTTP 报文;传输层加上 TCP 头(源端口、目的端口、序号、确认号、标志位),形成段(segment);网络层加上 IP 头(源 IP、目的 IP、TTL、协议号),形成包(packet);网络接口层加上以太网头(源 MAC、目的 MAC、类型),形成帧(frame),最后转成电信号或光信号发出去。接收端反过来逐层剥头,每一层只关心自己那一层的头部字段。
这个过程决定了排查思路:如果ping通但端口不通,说明网络层和链路层没问题,问题在传输层或应用层;如果ping不通但 ARP 能解析,说明问题在网络层路由或对端策略;如果连 ARP 都解析不了,问题在链路层或物理层。用tcpdump抓包时,你能看到的就是这些头部字段的集合,看懂封装顺序,抓包结果才不是黑匣子。
2.3 用 tcpdump 观察一次完整的分层封装
下面这条命令抓取本机与目标主机 80 端口的交互,-nn禁止域名和端口名解析,-i any抓所有网卡,-c 20抓 20 个包后停止:
# 抓取与 192.168.1.100 的 80 端口交互,显示 IP 和端口号,不解析域名 sudo tcpdump -i any -nn host 192.168.1.100 and port 80 -c 20执行后你会看到类似IP 192.168.1.10.54321 > 192.168.1.100.80: Flags [S]的行,Flags [S]表示 SYN,[S.]表示 SYN-ACK,[.]表示 ACK,[P.]表示 PSH-ACK。这些标志位就是传输层头部的内容。参数说明:-i any在 Linux 上抓所有接口,macOS 上需要指定具体接口如en0;-nn在排查时必加,否则 DNS 反解会拖慢输出;-c限制包数避免刷屏。如果只想看 TCP 标志位和序号,加-S显示绝对序号,方便对照握手过程。
提示:生产环境抓包前先确认磁盘空间和权限,
tcpdump写文件用-w,别直接刷终端,否则高流量下会丢包。
3. TCP 三次握手与四次挥手:连接建立和断开的每个状态
3.1 三次握手为什么不是两次或四次
TCP 是面向连接的可靠传输协议,三次握手的目的是双方同步初始序号(ISN)并确认对方收发能力正常。第一次客户端发 SYN,携带自己的 ISN=x;第二次服务端回 SYN-ACK,携带自己的 ISN=y 并确认 x+1;第三次客户端回 ACK,确认 y+1。两次不够,因为服务端无法确认客户端能收到自己的 SYN;四次多余,因为 SYN-ACK 把确认和同步合并了。
握手过程中客户端状态从 CLOSED 到 SYN_SENT 再到 ESTABLISHED,服务端从 LISTEN 到 SYN_RCVD 再到 ESTABLISHED。排查连接问题时,ss -ant看到的SYN-SENT堆积通常意味着 SYN 发出后没收到回应,可能是对端没监听、防火墙丢包或路由不可达;SYN-RECV堆积则可能是 SYN Flood 攻击或半连接队列满。半连接队列大小由net.ipv4.tcp_max_syn_backlog控制,全连接队列由listen()的 backlog 参数和net.core.somaxconn共同决定。
3.2 四次挥手与 TIME_WAIT 的真实含义
断开连接需要四次挥手:主动关闭方发 FIN,被动方回 ACK,被动方数据发完后发 FIN,主动方回 ACK。主动关闭方最后进入 TIME_WAIT,等待 2MSL(Linux 默认 60 秒)后才释放。TIME_WAIT 不是 bug,它保证最后一个 ACK 能到达对端,并让本次连接的迟到报文在网络中消散,避免影响复用同一四元组的新连接。
高并发短连接场景下 TIME_WAIT 会占满端口,常见做法是开启net.ipv4.tcp_tw_reuse(仅对出站连接生效)并调大net.ipv4.ip_local_port_range。但不要开tcp_tw_recycle,它在 NAT 环境下会导致连接随机失败,新内核已移除。查看当前 TIME_WAIT 数量:
# 统计各 TCP 状态连接数 ss -ant | awk 'NR>1 {state[$1]++} END {for (s in state) print s, state[s]}'这条命令跳过表头,按第一列状态字段计数。输出里TIME-WAIT数量持续偏高时,先确认是短连接业务还是连接池配置过小,再决定调参,别一上来就改内核。
3.3 用 ss 和 tcpdump 验证握手与挥手
服务端先起一个监听:
# 监听 8080 端口,-l 表示 listen,-k 表示保持连接 nc -lk 8080另一个终端抓包并连接:
# 抓 8080 端口握手包,-S 显示绝对序号 sudo tcpdump -i lo -nn -S port 8080 -c 10 # 另开终端发起连接 nc 127.0.0.1 8080你会看到[S]、[S.]、[.]三个包,序号从随机值开始递增。断开时按 Ctrl+C 结束nc,抓包会显示[F.]和[.]。参数说明:-i lo抓本地回环,本地测试必用;-S让序号可读,否则显示相对值。如果握手包只有 SYN 没有 SYN-ACK,检查服务端是否真的在监听(ss -lntp | grep 8080)以及防火墙规则(iptables -L -n或nft list ruleset)。
4. UDP 协议与打流测试:无连接场景怎么验证
4.1 UDP 头部结构与适用场景
UDP 头部只有 8 字节:源端口、目的端口、长度、校验和。它不建立连接、不保证顺序、不重传,因此延迟低、开销小。适合 DNS 查询、视频流、实时游戏、SNMP 以及 Modbus TCP 之外的很多工业协议。UDP 的“不可靠”不是缺陷,而是把可靠性交给应用层按需实现。排查 UDP 问题时不能看握手,只能看收发包计数和丢包率。
UDP 校验和是可选字段,IPv4 下可以置零表示不校验,IPv6 下强制校验。如果抓包看到校验和错误但应用正常,可能是网卡校验和卸载(checksum offload)导致抓包显示错误,实际包没问题。用ethtool -K eth0 rx off tx off可临时关闭卸载验证,但生产环境慎改。
4.2 用 iperf3 做 UDP 打流并解读丢包
iperf3 是常用的带宽和丢包测试工具。服务端:
# 服务端监听 5201 端口,UDP 模式由客户端指定 iperf3 -s客户端打 UDP 流,目标带宽 100M,持续 10 秒:
# -u 表示 UDP,-b 指定带宽,-t 指定时长,-c 指定服务端地址 iperf3 -u -c 192.168.1.100 -b 100M -t 10输出里关注Lost/Total Datagrams和Jitter。丢包率高时先降带宽再测,如果降带宽后丢包消失,说明链路或接收端处理能力不足;如果仍丢包,检查中间设备队列和 MTU。参数说明:-b 0表示不限速(UDP 下会尽力发),-l指定每个 UDP 包大小,默认 1460 字节,改小可降低分片概率。-R反向测试,让服务端发客户端收,用于排查单向链路问题。
4.3 UDP 分片与 MTU 的关系
UDP 包超过路径 MTU 时会在 IP 层分片。分片增加丢包概率,因为任一分片丢失整个包都要重传(如果应用层有重传)。以太网默认 MTU 1500,减去 IP 头 20 字节和 UDP 头 8 字节,UDP 载荷安全上限是 1472 字节。用ping探测路径 MTU:
# -M do 禁止分片,-s 指定载荷大小,1472+28=1500 ping -M do -s 1472 192.168.1.100如果返回Frag needed and DF set,说明路径 MTU 小于 1500,需要逐次减小-s直到通。参数说明:-M do在 Linux 下禁止分片,macOS 用-D。工业场景里 Modbus TCP 走 502 端口,报文通常很小,但批量读寄存器时仍要注意单包大小,避免分片导致 PLC 响应超时。
5. 排查网络问题时最容易翻车的几个地方
5.1 现象:ping通但端口不通,怀疑防火墙却查不到规则
原因:ping走 ICMP,端口走 TCP/UDP,两者可能被不同策略处理。云环境的安全组、主机防火墙、应用自身的访问控制列表是三层独立过滤,只查一层会漏。解决:按链路逐层确认——ss -lntp确认监听,iptables -L -n -v看包计数是否增长,nft list ruleset看 nftables,云控制台看安全组入方向。用nc -zv 目标IP 端口从客户端测,超时和拒绝含义不同:拒绝说明有 RST 回来,通常是端口没监听;超时说明包被丢,通常是防火墙或路由。
5.2 现象:TCP 连接建立后传输大文件卡住,小文件正常
原因:典型 MTU 或 MSS 问题。握手包小能通过,大数据包被中间设备丢弃且没有正确返回 ICMP 需要分片消息。解决:用ping -M do -s逐步探测路径 MTU,或在tcpdump里看是否有重传和分片。临时把接口 MTU 调小验证:ip link set dev eth0 mtu 1400。如果调小后正常,说明路径中有设备 MTU 小于 1500,需要调整两端 MSS 钳制:iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu。
5.3 现象:UDP 测试丢包严重,但带宽显示没跑满
原因:接收端 socket 缓冲区太小,内核来不及收就丢了。UDP 没有流控,发送端按-b指定速率发,接收端缓冲区满直接丢。解决:调大接收缓冲区sysctl -w net.core.rmem_max=26214400,应用里用setsockopt设SO_RCVBUF。同时确认 iperf3 服务端没有其他负载。用netstat -su看 UDP 错误计数,receive buffer errors增长就是缓冲区问题。
5.4 现象:ss看到大量SYN-RECV,服务响应变慢
原因:半连接队列满或遭遇 SYN Flood。net.ipv4.tcp_max_syn_backlog默认值偏小,高并发下不够用。解决:调大tcp_max_syn_backlog和somaxconn,开启net.ipv4.tcp_syncookies=1作为兜底。但 syncookies 会限制 TCP 选项,性能敏感场景先扩容队列。确认是否攻击看netstat -s | grep -i syn的 SYN 接收和丢弃计数。
5.5 现象:本地nc测试正常,跨主机就失败
原因:绑定地址不对。服务监听127.0.0.1只能本地访问,跨主机需要监听0.0.0.0或具体网卡 IP。解决:ss -lntp看监听地址,127.0.0.1:8080改成0.0.0.0:8080或::。容器环境还要确认端口映射和网络模式,docker run -p默认绑0.0.0.0,但-p 127.0.0.1:8080:8080只绑本地。
6. 把分层排查固化成习惯:一个可复用的检查顺序
我一般按固定顺序走,避免东一榔头西一棒子。第一步看链路和 IP:ip addr确认接口 up 且有地址,ip route确认默认路由,ping网关和目的 IP。第二步看传输层:ss -lntup确认监听,nc -zv测端口,tcpdump抓握手。第三步看应用层:curl -v或对应客户端看应用日志和返回码。第四步看统计:netstat -s、ss -s、ethtool -S找丢包和错误计数。
这个顺序的价值在于每一步都有明确的成功标准和失败分支。比如ping不通时不要急着抓包,先ip route get 目标IP看走哪个接口,再arping看链路层是否可达。tcpdump是最后手段,不是第一手段,因为抓包结果需要分层知识才能解读。
验证方法上,我习惯用iperf3做基线:先 TCP 测带宽,再 UDP 测丢包和抖动,记录正常值。出问题时对比基线,偏差超过 10% 再深入。参数上,TCP 测试用-P 4多线程压满带宽,UDP 用-b从低到高逐步加压找拐点。拐点出现的位置就是链路或接收端的瓶颈。
最后说个血泪教训:有次排查跨机房超时,抓包看到 SYN 重传,查了半天路由和防火墙,最后发现是两端 MTU 不一致导致大包被丢,握手包小所以能过。从那以后我养成了一个习惯——任何新链路先ping -M do -s 1472测一遍,不通就降 MTU 再测,五分钟能省几小时。网络问题大多不玄学,只是分层没看全。希望帮到你。
本文还有配套的精品资源,点击获取