尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TCP/IP协议栈详解:从四层模型到Wireshark排障实战

TCP/IP协议栈详解:从四层模型到Wireshark排障实战 做网络排查和通信联调做了十几年tcp/ip协议一直是我最依赖的主心骨。不管你是写后端接口、配交换机、搞IOT设备还是测视频流带宽最终都会绕回到这一套协议栈上。这篇想跟你认真聊聊 tcp/ip 协议从四层模型开始讲清楚数据从一端到另一端到底经历了什么再用 Wireshark、iperf、nc 这些工具把理论落到实操里最后分享几个我在真实环境中踩过的坑。如果你正在补网络基础、准备面试或者工作中频繁遇到能ping通但连不上重传多同网段不通这类问题这篇应该能在你脑子里把零散的知识点拼成一张完整地图。1. TCP/IP协议栈为什么分层这件事这么重要1.1 协议栈是通信的分工体系先说结论tcp/ip 不是一个协议而是一族协议的总称核心思想是分层。四层模型从上到下分别是应用层、传输层、网络层、链路层。用寄快递来类比很直观。你寄东西时只写地址、交给快递点不关心快递员开卡车还是坐飞机快递点也不关心你箱子里装的是书还是衣服。每一层只干自己这摊事把其余工作交给相邻层。TCP/IP 分层也是同一套逻辑应用层只生成业务数据传输层只负责端到端的可靠传输网络层只负责找路和寻址链路层只负责把数据变成帧发到物理线缆上。为什么要这么分最直接的原因是演进自由度。你从 HTTP/1.1 切到 HTTP/2、HTTP/3链路层和网络层完全不用动从有线网切换到 Wi-Fi应用层代码一行不用改。另一个好处是故障定位快。TCP 重传多我第一反应是怀疑链路质量和传输层参数不用把 HTTP 协议翻来覆去找问题。最后一层是生态兼容性同一套 IP 协议能跑在光纤、双绞线、4G/5G 上链路层差异被完全隔离在底层这对整个互联网的扩张太关键了。1.2 四层模型和OSI七层模型怎么对应经常有人把 TCP/IP 四层和 OSI 七层搞混。OSI 七层是理论上更细致的参考模型但现实中真正工程化的还是 TCP/IP 的四层模型。对应关系给一张表OSI七层TCP/IP四层代表的常见协议应用层、表示层、会话层应用层HTTP、HTTPS、DNS、FTP、SSH、MQTT、TLS传输层传输层TCP、UDP网络层网络层IP、ICMP、ARPARP 也有人归链路层数据链路层、物理层链路层以太网、Wi-Fi、PPP、VLAN实际工作中把表示层、会话层单独拎出来讲的机会很少。JSON、XML 这种表示格式本质属于应用层自己定义的载荷格式TLS 虽然教科书上挂在应用层但它真实工作在 TCP 之上、为应用层提供加密排查 HTTPS 问题时你需要知道这条链路是HTTP - TLS - TCP - IP。我见过很多新手死记 OSI 七层到了抓包环节还是不会看报文原因就是少了四层模型这个工程简化。学协议栈要从 TCP/IP 四层入手OSI 七层只需要知道怎么对应真正排障时不会应会话层引入额外复杂度。2. 数据在TCP/IP模型中传输的完整过程2.1 发送端从浏览器输入URL到网卡发比特以访问一个网站为例假设 DNS 已经把域名解析成 IP浏览器生成 HTTP 请求后数据在协议栈里逐层向下走每一层都会在载荷前面加一个头部这个过程叫封装Encapsulation。具体步骤拆开看应用层浏览器构造 HTTP GET 报文包含请求行、Header、可能的 Body这是整个传输过程的业务载荷。传输层TCP 拿到 HTTP 报文把它当成载荷在前面加上 TCP 头。这个头里最重要的字段是源端口比如随机分配的 54321和目的端口80 或 443还有序号、确认号、窗口大小。这层封装完的对象叫 TCP 段Segment。网络层IP 把 TCP 段整体当成载荷加上 IP 头。头里包含源 IP、目的 IP、TTL、协议号6 是 TCP17 是 UDP。这层封装完对象叫 IP 包Packet。链路层以太网驱动把 IP 包加上以太网头包含源 MAC 地址、目的 MAC 地址帧尾部再附一个校验序列。这层对象叫帧Frame最后由网卡转成物理信号发出去。封装过程可以这样记HTTP 报文应用层载荷加 TCP 头得到 TCP 段加 IP 头得到 IP 包加以太网头/尾得到以太网帧这里有个容易被忽略的点每加一层头部都会增加额外的开销字节Wireshark 里看到的 Length 字段是包含所有头部之后的长度。抓包时如果发现数据包大小比应用消息大很多先检查是不是 MTU、TLS 记录等导致的头部膨胀。2.2 接收端从网卡收帧到浏览器渲染接收方向是发送方向的逆过程专业说法叫解封装De-encapsulation或者叫分用Demultiplexing。数据到达对端网卡后网卡收到帧先检查目的 MAC 是否匹配本机不匹配直接丢弃匹配则去掉以太网头尾把里面的 IP 包交给 IP 层。IP 层检查目的 IP 是否为本机地址再查头部里的协议号如果是 6 就把载荷交给 TCP 协议栈处理如果是 17 就交给 UDP 协议栈。TCP 根据端口号找到对应的 socket 连接如果这个端口有应用在 listen就把数据放进接收缓冲区如果没有任何进程监听大概率会回一个 RST 复位包这就是连接被拒绝的底层来源。应用进程通过 read/recv 从 socket 缓冲区拿到 HTTP 请求交给 HTTP 解析器处理业务逻辑开始运行然后再把 HTTP 响应按同样的封装备路径返回。理解分用机制之后很多问题就通了。比如你抓包看到某个端口回 RST第一反应不应该是防火墙拦截而是先查本机到底有没有进程监听这个端口、监听在 IPv4 还是 IPv6 上。IPv6 环境下经常出现服务只监听了::导致 IPv4 连接被拒的案例。2.3 MTU、分片与重组大数据包怎么传链路层一帧最多能装多少数据是关键约束。标准以太网的 MTUMaximum Transmission Unit最大传输单元是 1500 字节。如果 IP 包大于链路 MTUIP 层就得分片Fragmentation把一个大包切成多片分别发送接收端再按顺序重组。IP 分片依赖三个头部字段16 位标识符Identification同一原始包的所有分片共用同一个标识符。3 位标志位DFDont Fragment为 1 时禁止分片MFMore Fragments为 1 表示后面还有分片。13 位片偏移Fragment Offset记录当前分片在原数据报中的位置。TCP 的设计比 IP 聪明TCP 在三次握手阶段会协商 MSSMaximum Segment Size直接把 TCP 段大小控制在本链路的 MTU 之内从而避开 IP 分片。常见的值是 MSS MTU 减去 40 字节20 字节 IP 头 20 字节 TCP 头也就是 1460 字节。这也是 TCP 传输效率高的重要原因IP 层基本不需要分片。但如果用 UDP 一次性发送一个超过 MTU 的报文IP 层就会进行分片而分片的致命弱点是任意一片丢失整个 IP 包都无法重组而且 UDP 又没有重传机制对应用层来说就是数据丢了。所以在实际开发中UDP 的单包载荷一定要控制在安全范围通常建议小于 1400 字节这比依赖 IP 分片可靠得多。3. 核心协议细节IP、TCP、UDP该掌握到哪一层3.1 IP协议寻址和路由的基础IPv4 头部最关键的字段我个人认为是这几个版本4 位IPv4 是 4IPv6 是 6。总长度16 位整个 IP 包长度单位是字节最大表示 65535。TTL8 位每经过一个路由器减 1减到 0 就丢弃。这个字段的目的是防止环路让数据包无限转发。协议8 位识别上层协议6 是 TCP17 是 UDP1 是 ICMP。源 IP、目的 IP各 32 位。头部校验和16 位只校验 IP 头本身快速识别损坏的头部。现在的互联网公网 IPv4 早已枯竭但企业内部大量在用私有地址段192.168.x.x、10.x.x.x、172.16.x.x~172.31.x.x。私网地址靠 NAT网络地址转换访问公网这也会引出排障中的一个经典问题很多协议在 NAT 环境下需要特殊处理比如 FTP 的主动模式会失败因为内网地址被封装在数据里NAT 无法自动改写。路由的核心逻辑就是下一跳。一个路由器并不需要记住全网主机的位置它只需要维护路由表查询目标地址所在网段的下一跳是谁数据包一层一层转发下去。这也是 Traceroute 命令的工作原理通过逐渐加大 TTL让每一跳路由器都回一个 ICMP 超时报文就能把路径上的所有节点逼出来。3.2 TCP可靠传输是如何做到的TCP 最核心的四个机制是连接管理、确认重传、滑动窗口和拥塞控制。连接管理是面试和排障都绕不开的内容先看三次握手客户端发送 SYN 包携带初始序号 seqx。服务端回 SYNACK 包携带自己的序号 seqy确认号 ackx1。客户端再回 ACK 包序号 seqx1确认号 acky1。三次握手完成后双方各自知道我能发、你能收你能发、我能收。为什么不是两次握手因为网络中有可能滞留一个历史失效的 SYN 请求。如果只有两次握手服务端收到旧请求后盲目建立一个半连接浪费资源三次握手让服务端能通过收到客户端回应的 ACK 确认这是一个新鲜请求降低了误建连接的概率。四次挥手对应四条报文主动关闭方发 FIN被动方回 ACK被动方发 FIN主动方回 ACK为什么挥手要四次、握手只要三次TCP 是全双工的每个方向的关闭相互独立。收到对方 FIN 只表示对方不再发数据自己这边可能还有数据没发完所以要单独再发一次 FIN于是多了两步。主动关闭方最后还要进入 TIME_WAIT 状态等待 2MSL 时间目的是确保最后的 ACK 能有重传机会否则被动方重发 FIN 时主动方已经关闭了就会收到 RST。可靠传输的落地机制超时重传发送方设置一个 RTO 计时器超时未收到 ACK 就重发。快速重传收到连续三个重复 ACK理解为后续数据丢了不等超时直接重传。滑动窗口接收方通过 TCP 头里的窗口大小告诉发送方我还能收多少这是流量控制防止接收方缓冲区溢出。拥塞控制慢启动、拥塞避免、快速重传、快速恢复。Linux 下可以通过ss -i看当前的拥塞窗口和 RTT排障时很有用。实际抓包时判断 TCP 是否健康最先看两个指标重传次数和接收窗口。重传多大概率是链路丢包或拥塞接收窗口经常压到 0大概率是应用层消费太慢问题在业务代码而不是网络。3.3 UDP无连接到底省了什么UDP 头只有 4 个字段源端口、目的端口、长度、校验和。相比 TCP 的 20 字节起步UDP 头部只有 8 字节没有序号、确认、窗口、握手状态。但简洁就是最大的价值。UDP 的优势主要体现在三件事延迟低不需要三次握手和四次挥手省掉来回 RTT对秒开首帧、语音通话这种实时场景关键。开销小8 字节头对物联网小包和 DNS 查询性价比很高。应用层可控可靠传输逻辑可以完全自定义不会像 TCP 那样有队头阻塞问题。近几年最值得关注的 UDP 应用是 QUIC。HTTP/3 底层改用 QUIC而 QUIC 跑在 UDP 上在用户态自己实现了可靠传输、拥塞控制和连接迁移。为什么要绕开 TCP因为 TCP 的实现在操作系统内核里升级和改动周期太长且单个 TCP 连接内部的队头阻塞很难解决在弱网下影响明显。QUIC 把可控性握在手里是协议演进思路的一个典型代表。日常见的 UDP 协议还有DNS 查询超过 512 字节会切 TCP、DHCP 分配 IP、SNMP 网管、RTP 音视频传输。如果你要学习 MQTT 这类 IoT 协议默认实现通常选 TCP 作为可靠传输但部分 MQTT 变体也可以跑在 WebSocket 或 UDP 之上选择时要先想清楚你的物联设备对功耗、实时性、丢包恢复的优先级。4. 实战演练用抓包和压测工具验证理论4.1 Wireshark抓包亲眼看一次HTTP请求Wireshark 是图形化抓包的第一选择也是验证协议理论上手最快的工具。操作步骤说细一点打开 Wireshark选择正确的网卡。Windows 一般选以太网或 WLANMac 上常见 en0。选错网卡会看到一堆无关流量。设置显示过滤条件比如tcp.port 80或http把无关包过滤掉方便快速定位。打开浏览器访问一个 HTTP 明文网站比如http://example.com。不用 HTTPS 的原因是加密内容 Wireshark 直接看载荷是一堆二进制明文 HTTP 更容易观察结构。停止抓包找到三次握手的三个包SYN、SYNACK、ACK这是每一对 TCP 连接开局的固定套路。选中一条 HTTP GET 报文逐层展开以太网层看源目的 MACIP 层看源目的 IP 和 TTLTCP 层看端口、序号、确认号、窗口、选项应用层看 HTTP 请求行和 Header。如果你想判断一次请求的时间花在哪段可以用Statistics TCP Stream Graph Time-Sequence (Stevens)看序列号随时间的变化曲线。如果曲线斜率高说明传输顺畅如果出现大量水平线说明中间有等待或重传。一个小经验在 Windows 上用 Wireshark 抓本机回环流量需要安装 Npcap 并勾选支持回环流量的选项Linux 上抓 loopback 接口直接选择 lo 网卡即可。4.2 iperf端到端带宽测试iperf3 是网络测速最常用的工具不管是局域网验证还是云服务器链路评估都会用到。先看服务端iperf3 -s -p 5201客户端测 TCP 带宽iperf3 -c 192.168.1.100 -p 5201 -t 10 -P 4参数含义-s服务端模式默认监听 5201 端口。-c客户端模式后跟服务端 IP。-p指定端口。-t测试时长单位秒。-P并发流的数量多个流可以更好地压满带宽。-i每隔几秒打印一次中间结果。-uUDP 模式UDP 测试时还要用-b指定目标带宽比如-b 100M。测 UDP 的例子iperf3 -c 192.168.1.100 -u -b 100M -t 10 -i 1结果最需要关注的字段Bitrate实测带宽。TCP 测试里如果接近链路标称值说明网络基本没问题。RetrTCP 重传次数。结果末尾的Retr数据如果持续增长说明链路或缓冲有问题。Jitter 和 LostUDP 模式重点看抖动和丢包率。语音视频质量差基本就是这两个指标超标。实测中两个容易踩的坑一是两端 iperf3 版本要一致否则可能报协议错误或参数不兼容二是云服务器默认安全组通常不放行 5201 端口测试前必须先把端口放行否则客户端会一直卡在连接阶段。4.3 curl和nc快速发包收包的轻量工具curl 不只是下载工具排查 HTTP 接口时它是第一梯队的选手curl -v http://192.168.1.10:8080/api/hello-v会打印出 TCP 连接、TLS 握手如果地址是 https、HTTP 请求行、响应码和耗时统计。我的习惯是用这个命令配合超时参数快速区分问题阶段curl -v --connect-timeout 3 --max-time 10 http://192.168.1.10:8080/api/hello如果connect-timeout超时问题在网络层如果连接建立但max-time超时问题往往是服务端处理慢或响应体过大。ncnetcat是另一个调试利器做端口监听和原始数据收发都靠它。服务端监听nc -l 9000客户端连过去并发送数据echo hello | nc 192.168.1.10 9000nc 在端口通不通的排查里价值极大。先在本机nc -l监听再用另一台机器去连能直接区分端口没监听和防火墙拦截。很多防火墙对 ICMP 无响应但 TCP 端口其实是通的所以别只信 ping要会同用 nc 或者 telnet。5. 日常网络排查中的高频问题5.1 连接建立失败是防火墙还是路由黑洞TCP 连接建立失败是排障单里出现频率最高的类别。我的排查顺序固定如下确认本机到目标网络通不通ping 目标IP观察丢包和 RTT。确认目标端口通不通nc -vz 目标IP 端口或telnet 目标IP 端口。同时抓包tcpdump -i eth0 host 目标IP and tcp port 80看 SYN 有没有发出去、有没有 SYNACK 回来。根据结果分段判断ping 不通目标先看是否同网段、本地路由表有没有默认路由。ping 通但端口不通继续分是目标服务没起来、本机防火墙拦截、还是中间安全设备丢包。SYN 发出去了但没回包大概率是中间防火墙静默丢弃。回了 RST 包大概率是目标端口没有服务在监听或者应用主动拒绝。Linux 下查看端口监听的命令ss -tnlp | grep 80Windows 下netstat -ano | findstr :80这套流程看起来简单但能覆盖九成以上的连不上问题。核心思路是不要把时间和精力耗在猜测上而是用工具把故障边界一层层切出来。5.2 重传率过高网络质量差还是缓冲太小抓包看到大量 TCP 重传时不要第一反应就甩锅给网络差。重传多的常见原因有几种链路不稳定无线环境波动、干扰严重丢包率高。链路拥塞瞬时流量超过链路能力中间设备队列溢出丢包。接收端处理慢应用进程不读 socket 缓冲区接收窗口缩到 0发送端堆积数据最终超时重传。TCP 参数不合适比如窗口太小、RTO 过短、网络乱序导致大量重复 ACK。排查步骤在 Wireshark 里统计重传包数量Statistics TCP Analysis Flags看重传比例。用 UDP 模式跑 iperf3 测真实丢包率TCP 重传是结果UDP 丢包率才是更底层的原因。对症处理无线链路问题换有线或者调整无线频段和信道减少干扰。瞬时拥塞降低发送速率或者检查交换机端口的 buffer 是否过小。应用层读数据慢这往往是业务代码问题要抓应用日志看线程阻塞而不是继续折腾网络设备。TCP 参数Linux 下可调net.ipv4.tcp_sack、net.core.rmem_max、net.core.wmem_max等但改动前先在测试环境验证。一个我实测踩过的场景两台无线路由器做桥接信号强度显示 -65dBm看着还行延迟也不高但跑 iperf 时 TCP 重传经常上百。后来用 UDP 模式一测丢包率高达 8%。这个案例说明TCP 表现不好时一定要绕开 TCP 的可靠机制直接用 UDP 探链路底子。链路丢包、乱序、抖动UDP 一眼就能看到。5.3 ARP问题同网段却不通网络层虽然靠 IP 通信但真正找到同网段设备靠的是 ARPAddress Resolution Protocol它负责把 IP 解析成 MAC 地址。典型症状ping 同一网段的机器超时但arp -a或者ip neigh show能看到对方 IP要么 MAC 不对要么根本没有映射记录。排查命令Windowsarp -aLinuxip neigh show常见原因对方防火墙禁 pingping 不通不代表 TCP 也不通直接用 nc 测端口更可靠。交换机端口安全限制端口启用了 MAC 地址白名单新设备 MAC 不被接受。IP 冲突两台设备配了同一个 IPARP 缓存里的 MAC 像变脸一样反复跳。静态 ARP 绑定错误有人手工绑了 IP 到错误的 MAC。判断 IP 冲突可以用 arpingarping -I eth0 192.168.1.100如果同一个 IP 有多个 MAC 地址应答基本就是 IP 冲突了两台设备抢地址通信时好时坏。这种问题在动态分配和手工静态配置混用的办公网络里特别常见。6. 继续深入的方向和小建议6.1 从应用层反推学习很多初学者一上来就背 OSI 七层背得很熟练真到抓包排障时还是不知道 tcpdump、ss、curl 怎么用。我的建议是别从底层往上学从应用层反推。你每天用的软件背后都是协议浏览器用 HTTP/HTTPS底层是 TCP。域名解析用 DNS默认走 UDP大响应会切 TCP。文件传输用 FTP/SFTPFTP 用 TCPSFTP 底层是 SSH也是 TCP。物联网设备用 MQTT一般跑 TCP轻量级场景用 CoAP基于 UDP。视频直播可能用 RTMPTCP或 SRTUDP各有取舍。办公网里的 Windows 共享、打印服务用 SMB也是 TCP。每遇到一个应用就往下追问三层它用 TCP 还是 UDP它的端口号是什么IP 层怎么找到目标主机链路层封装成多少字节的帧这样一次一次追问知识就串起来比单纯背书深刻得多。另外不要把 TCP/IP 这套网际协议和单片机里的 SPI、I2C、UART、CAN 这类板级总线混为一谈它们的适用范围完全不同一个是机器间通信另一个是板卡内芯片间通信。6.2 长期有用的工具清单日常维护和排障我固定会带这几样tcpdumpLinux 命令行抓包最轻量适合远程环境快速定位。Wireshark图形化深度分析适合本地慢慢拆解报文。iperf3链路带宽、抖动、丢包测试的标准工具。nc/ncatTCP/UDP 端口测试和原始数据收发。curlHTTP 接口调试和延迟判断。ping/arping/traceroute基础连通性、ARP 探测、路由路径追踪。ss/netstat本机连接状态、端口监听、连接队列。ip/ifconfig网卡配置、路由表、链路状态。这套工具覆盖九成以上的日常排障场景。学的时候不要贪多先把每个工具最核心的用法练熟比如 tcpdump 至少要知道-i、host、port、tcp、-w这几个参数Wireshark 至少要学会设置显示过滤条件和看 TCP 流。6.3 我踩过的几个坑最后分享几个实操教训都是真实工作里反复碰过的抓包前先确认网卡和过滤条件。我见过有人抓了几百兆数据才发现完全不是自己要看的流量。抓包之前先用一句话写清楚我要看谁到谁、什么协议、什么端口再设置过滤条件。Wireshark 里看到的 TTL 是包发出后的当前值不是原始值。判断经过了几跳需要拿系统默认初始值减去当前值再用 traceroute 验证。iperf 测带宽前先检查两端 MTU 是否一致。如果两端 MTU 差距大可能出现大包不通、小包正常的现象应用层被误判成慢实际上是分片和丢包在捣乱。TCP 重传不一定代表网络差。先看接收窗口是不是被压到 0再看应用进程的 CPU 和磁盘状态很多网络问题最后定位到的是开发者没有及时消费 socket 数据。协议栈是相对死的真实环境是活的。多抓包、多动手、多记录慢慢就会形成手感。这套内容你可以照着抓一遍包、跑一遍 iperf、做一轮排查演练比只看理论要实用得多。
返回列表