ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

计算机网络基础知识实战:从抓包翻车到TCP/UDP排障与Wireshark技巧

计算机网络基础知识实战:从抓包翻车到TCP/UDP排障与Wireshark技巧 简介这份PDF资料面向准备技术面试的IT求职者与网络初学者系统梳理计算机网络核心考点帮助读者在面试与工程实践中快速定位知识盲区。内容围绕OSI七层参考模型与TCP/IP四层模型展开涵盖TCP/IP协议族、TCP/UDP/SCTP协议对比、三次握手与四次挥手、TCP状态机、TIME_WAIT状态、端口号、超时重传与快速重传、TCP Header结构、可靠传输、流量控制与拥塞控制以及IPv4/IPv6、ICMP、ARP、RARP、IGMP等网络层协议并附有OSI与TCP/IP模型区别等常见面试问题解析。资源包共1个PDF文件大小约2.08MB单文件结构便于通读与检索。目前已有969人学习适合需要系统复习网络基础、对照面试题查漏补缺的读者可作为面试冲刺与日常查阅的参考材料。1. 计算机网络基础知识从一次抓包翻车说起很多人对「计算机网络基础知识」的印象停留在考试背题——OSI 七层、TCP 三次握手、UDP 无连接背完就忘。但我真正意识到这些基础值钱是因为一次线上事故两台内网机器之间传文件iperf3打流跑出来只有 2 Mbps排查了半天以为是网线问题最后抓包发现是 MTU 不匹配导致 IP 分片大量分片在中间设备被丢弃。那一刻我才明白OSI 七层模型和 TCP/IP 协议栈不是拿来考试的是拿来定位问题的坐标系。这篇笔记面向两类人一是刚接触网络编程、想搞清数据从应用到网线到底经历了什么的新手二是写过 socket 但遇到「能连上却传不动」「UDP 丢包不知道从哪查」这类问题、需要一套可复现排查路径的熟手。我会从分层模型讲到 TCP/UDP 的实操差异再落到抓包、打流、参数调优的具体命令每一步都能在你自己的机器上跑一遍。不聊虚的只讲能复现的。2. OSI 七层与 TCP/IP 四层分层到底怎么帮你定位问题2.1 两套模型不是对立的是同一件事的粗细粒度初学者最容易卡在「OSI 七层和 TCP/IP 四层到底学哪个」。结论很简单排障时用 TCP/IP 四层做骨架用 OSI 七层做细分。TCP/IP 模型是工程实现OSI 是教学参考两者对应关系如下。OSI 七层TCP/IP 四层典型协议排障时看什么应用层 / 表示层 / 会话层应用层HTTP、DNS、Modbus TCP业务日志、请求响应内容传输层传输层TCP、UDP端口、连接状态、重传、丢包网络层网络层IP、ICMP、IGMPIP 地址、路由、分片、TTL数据链路层 / 物理层网络接口层Ethernet、ARP、Wi-FiMAC、网卡状态、CRC 错误这张表的价值在于当你拿到一个「网络不通」的问题可以按层自下而上排除。先看网卡灯亮不亮物理层再看arp -a有没有对端 MAC链路层再ping通不通网络层再telnet ip port端口通不通传输层最后才看应用日志。这个顺序能帮你避免「一上来就怀疑代码」的常见误判。2.2 数据在 TCP/IP 模型中的封装与解封装过程理解封装是理解一切网络行为的前提。以你用浏览器发一个 HTTP 请求为例数据往下走的每一步都会加一个头# 用 tcpdump 抓一个 HTTP 请求直观看到每一层的头 sudo tcpdump -i eth0 -nn -vvv tcp port 80 and host 93.184.216.34 -c 5抓到的包用 Wireshark 打开你会看到从下到上依次是Ethernet II源/目的 MAC→ IPv4源/目的 IP、TTL、协议号→ TCP源/目的端口、序列号、标志位→ HTTP请求行、头部。每一层只关心自己的头不关心上层载荷这就是分层的核心思想。封装的关键参数有三个必须记住MTU最大传输单元以太网默认 1500 字节。IP 层如果发现上层数据超过 MTU要么分片要么通知 TCP 调整 MSS。分片是性能杀手后面避坑章节会细讲。MSS最大报文段长度TCP 握手时双方协商通常 MTU - IP 头(20) - TCP 头(20) 1460。这是 TCP 不分片的保证。TTL生存时间每经过一个路由器减 1减到 0 丢弃并回 ICMP 超时。traceroute就是靠这个工作的。2.3 用 ping 和 traceroute 验证网络层连通性网络层排障的两个基本命令很多人只会用不会读输出。# 1. ping 指定源接口和包大小验证 MTU 是否匹配 ping -I eth0 -s 1472 -M do 192.168.1.1 # -s 1472 表示数据部分 1472 字节加上 ICMP 头 8 IP 头 20 1500正好等于 MTU # -M do 表示禁止分片如果对端 MTU 小于 1500这里会直接报错 # 2. traceroute 看路径-n 不解析 DNS-I 用 ICMP 探测 traceroute -n -I 8.8.8.8ping -s 1472 -M do这个组合是排查 MTU 问题的黄金命令。如果小包能通、大包不通基本可以锁定路径上某段 MTU 小于 1500。traceroute输出里如果某一跳之后全是*说明那台设备不回应 ICMP不一定是断了可以换-T用 TCP 探测。提示Windows 下对应命令是ping -l 1472 -f-f表示禁止分片tracert替代traceroute。3. TCP 与 UDP 的实操差异三次握手、四次挥手与打流验证3.1 TCP 三次握手不是背出来的是抓出来的「TCP 三次握手」被背烂了但真正抓一次包理解会完全不同。# 在一台机器上监听另一台机器连接同时抓包 # 服务端先启动 nc -l 9999 # 客户端 nc 192.168.1.100 9999 # 第三个终端抓包 sudo tcpdump -i any -nn tcp port 9999 -c 10你会看到三个包SYN→SYNACK→ACK。关键在序列号的变化客户端发 SYN 时带一个随机初始序列号seqx服务端回 SYNACK 时带自己的seqy并确认ackx1客户端最后发 ACK 确认acky1。三次握手的本质是双方各自确认对方的收发能力都正常两次不够服务端无法确认客户端能收到四次多余。四次挥手同理因为 TCP 是全双工每个方向要单独关闭所以是FIN→ACK→FIN→ACK。主动关闭方最后会进入TIME_WAIT状态等 2MSL通常 60 秒才释放。这个状态在高并发短连接场景下会耗尽端口是后端常见的坑。3.2 UDP 无连接不等于不可靠关键看你怎么用UDP 常被说成「不可靠」但它的不可靠是指不保证到达、不保证顺序、不保证不重复不是「不能用」。实时音视频、DNS、游戏同步、Modbus 广播都靠 UDP。用 UDP 的正确姿势是在应用层自己补机制。# Python UDP 发送端加序号和简单重传 import socket import struct import time sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(0.5) # 设置超时用于重传判断 def send_with_retry(data, addr, seq, max_retry3): # 包头加 4 字节序号方便接收端去重和排序 packet struct.pack(!I, seq) data for i in range(max_retry): try: sock.sendto(packet, addr) ack, _ sock.recvfrom(1024) # 等 ACK if ack bOK: return True except socket.timeout: print(fseq{seq} 第 {i1} 次超时重传) return False for seq in range(10): ok send_with_retry(fpayload-{seq}.encode(), (192.168.1.100, 9999), seq) print(fseq{seq} 发送{成功 if ok else 失败})这段代码演示了 UDP 上做可靠传输的最小骨架序号用于去重和排序超时重传用于保证到达ACK 用于确认。参数上settimeout(0.5)要根据你的网络 RTT 调整局域网 0.1 秒够跨公网可能要 1 秒以上。max_retry3是经验值再多说明链路本身有问题重传也救不回来。3.3 用 iperf3 分别打 TCP 和 UDP 流看差异iperf3是验证链路质量的标准工具TCP 和 UDP 模式行为完全不同。# 服务端 iperf3 -s # TCP 打流默认就是 TCP-t 时长-P 并发数 iperf3 -c 192.168.1.100 -t 10 -P 4 # UDP 打流-u 开启 UDP-b 指定带宽-l 指定包大小 iperf3 -c 192.168.1.100 -u -b 100M -l 1400 -t 10TCP 模式下iperf3会自动做拥塞控制你看到的是实际能达到的吞吐如果远低于链路带宽说明有丢包或延迟。UDP 模式下-b 100M是你强制发送的速率iperf3会报告丢包率和抖动jitter。UDP 打流的意义在于测链路极限逐步提高-b直到丢包率超过 1%那个点就是链路实际能承载的 UDP 吞吐。-l 1400这个包大小有讲究1400 8(UDP头) 20(IP头) 1428小于 1500避免分片。如果你设-l 1472加上头正好 1500某些设备可能因为额外封装如 VLAN 标签导致分片。注意UDP 打流会占满带宽生产环境慎用最好在维护窗口或独立测试链路做。4. 避坑与排查五个让我加班到凌晨的网络问题4.1 现象小包能 ping 通大包全部超时原因路径上某段 MTU 小于 1500通常是 PPPoE 拨号MTU 1492或隧道封装。大包被要求分片但设置了 DF 标志直接被丢弃。解决用ping -s 1472 -M do逐步减小-s值找到能通的最大值那个值 28 就是实际 MTU。然后在应用层把发送缓冲区控制在 MTU 以内或调整网卡 MTUip link set eth0 mtu 1400。4.2 现象TCP 连接建立成功但传输大量数据时卡死原因典型的 MSS 协商问题。握手时双方协商的 MSS 是基于自己网卡的 MTU但路径中间有更小 MTU 的设备且 ICMP 被防火墙拦截导致 PMTUD路径 MTU 发现失效。解决在服务端显式设置 MSS clampiptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu。或者直接在应用层限制单次发送大小。4.3 现象UDP 服务端recvfrom报Connection reset by peer或unknown error 10054原因Windows 下如果 UDP 发送方给一个未监听的端口发过包对端会回 ICMP 端口不可达Windows 把这个 ICMP 错误上报给了下一次recvfrom调用。这是 Windows 特有的行为Linux 默认不报。解决用SIO_UDP_CONNRESET关闭这个行为// Windows 下关闭 UDP 连接重置上报 #include winsock2.h #include mstcpip.h BOOL bNewBehavior FALSE; DWORD dwBytesReturned 0; WSAIoctl(sock, SIO_UDP_CONNRESET, bNewBehavior, sizeof(bNewBehavior), NULL, 0, dwBytesReturned, NULL, NULL);参数说明SIO_UDP_CONNRESET是控制码传入FALSE表示不接收 ICMP 重置错误。这段代码要在socket()之后、recvfrom()之前调用。4.4 现象iperf3UDP 打流丢包率极高但 TCP 打流正常原因UDP 没有拥塞控制你设的-b超过了链路实际承载能力或者中间设备对 UDP 做了限速很多企业网关会限制 UDP 带宽防止 P2P。解决先用 TCP 打流测出实际带宽UDP 的-b设为 TCP 结果的 80% 左右。如果 UDP 丢包但 TCP 正常基本可以确认是中间设备限速需要找网络管理员确认策略。4.5 现象服务端大量TIME_WAIT新连接建不上原因短连接高并发场景主动关闭方会进入TIME_WAIT等 2MSL端口被占用。Linux 默认本地端口范围约 28000 个如果 QPS 高很快耗尽。解决三个方向——开启tcp_tw_reuse复用sysctl -w net.ipv4.tcp_tw_reuse1让客户端主动关闭改为服务端被动关闭或者改用长连接。注意tcp_tw_recycle在新内核已移除不要再用。提示ss -s可以快速看当前连接状态统计ss -tan state time-wait | wc -l看 TIME_WAIT 数量。5. 进阶技巧用 Wireshark 过滤器把排障时间砍一半前面讲的都是命令行但真正定位复杂问题Wireshark 的显示过滤器是效率倍增器。我一般会先抓全量包再用过滤器逐层缩小范围。常用的过滤器组合按排障场景分场景过滤器说明看某个 TCP 流tcp.stream eq 5右键包 → Follow → TCP Stream 可拿到流号看重传tcp.analysis.retransmission重传多说明链路丢包或拥塞看零窗口tcp.analysis.zero_window接收方缓冲区满发送方被暂停看 UDP 丢包udp !icmp结合序号看哪些序号缺失看 IP 分片ip.flags.mf 1 || ip.frag_offset 0有分片说明 MTU 有问题看 DNS 慢dns.time 0.5响应超过 500ms 的 DNS 查询我自己的习惯是先看tcp.analysis.flags有没有异常标志再看tcp.time_delta有没有大间隔。大间隔通常意味着应用层处理慢或网络抖动比看吞吐更直观。还有一个技巧是给抓包文件加时间戳标记。在关键操作前后用echo打时间点抓包时用-w存文件事后用frame.time过滤对齐# 抓包存文件同时记录操作时间点 date %s.%N /tmp/mark.txt sudo tcpdump -i eth0 -w /tmp/capture.pcap host 192.168.1.100 # 复现问题后 CtrlC用 Wireshark 打开按 frame.time 排序最后说一个我踩过的坑不要在生产高峰期抓全量包。tcpdump默认缓冲区 2MB高流量下会丢包你抓到的包本身就不完整分析结论全是错的。正确做法是用-B加大缓冲区单位 KB或者用-s 96只抓包头减少数据量。# 生产环境安全抓包只抓包头加大缓冲限制包数 sudo tcpdump -i eth0 -s 96 -B 4096 -c 10000 -w /tmp/cap.pcap tcp port 8080-s 96表示每个包只截取前 96 字节足够看到以太网头、IP 头、TCP 头但看不到应用层载荷适合分析连接和重传问题。-B 4096把缓冲区加到 4MB-c 10000抓够一万个包自动停避免磁盘写满。这套方法我用了三年从最初的「抓包看不懂」到现在「打开 Wireshark 五分钟定位」核心就一句话分层看逐层过滤先看异常标志再看时间间隔。网络基础知识的价值不在背在于你遇到问题时脑子里有没有那张分层图。希望帮到你。本文还有配套的精品资源点击获取
返回列表