ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

TCP/IP协议族详解:从分层模型到抓包排查实战

TCP/IP协议族详解:从分层模型到抓包排查实战 干这行这么多年带过不少新人也面试过一堆网络岗位的候选人几乎每次聊到基础都绕不开TCP/IP协议族。很多朋友一说TCP/IP就只知道三次握手、四次挥手稍微问深一点就卡壳。说实话这玩意儿要是只停留在背概念的程度后面排查问题、抓包分析、读懂文档全都会很吃力。今天我就把“2.3 TCPIP协议族”这个章节好好掰开揉碎讲一遍把那些教材里写得云里雾里、或者干脆没写的东西都补上希望能帮到正在啃书的学生党也帮到想系统性补基础的职场人。很多人第一反应是TCP/IP不就是TCP和IP两个协议吗这个理解太狭隘了。TCP/IP协议族是一个庞大的协议集合TCP和IP只是其中最核心的两个成员。就像你叫“张家班”班里不只有张老三和张老四还有一大堆师兄弟。协议族里的每个协议都有自己的分工有的管寻址有的管可靠传输有的管域名解析有的管文件传输它们协作配合才有了我们今天畅通无阻的网络通信。1. 整体架构与设计思路拆解1.1 为什么叫协议族而不是协议栈日常交流里很多人把“协议栈”和“协议族”混着用这其实没什么大毛病但严格抠起来两个词侧重点不一样。协议族Protocol Family强调的是协议的“集合”属性也就是说TCP/IP名下到底有哪些协议成员协议栈Protocol Stack强调的是协议的“分层”结构突出数据在每一层的封装和解封装过程。我更愿意用“分层模型”来理解TCP/IP协议族的设计思路。教材上常把TCP/IP分成四层应用层、传输层、网络层、网络接口层。有人会问“那OSI七层模型呢”其实TCP/IP四层模型和OSI七层模型本质上是同一件事的两种描述方式。OSI搞得特别细把表示层、会话层单独拿出来但实际工程中这两层的功能大都被应用层协议自己消化了。所以TCP/IP模型更贴近真实网络设备的运转逻辑。我讲课的时候喜欢用“发快递”来类比这套分层体系。应用层你写好了一封信信的内容就是你发给对方的应用数据比如一个HTTP请求、一封邮件。传输层你把信装进一个信封信封上标注了“这封信要送到对方哪个门端口”是“普通平信”UDP还是“需要签收的挂号信”TCP。网络层你的信随着一大堆信件汇入邮政分拣中心分拣系统会根据“门牌号”IP地址规划出一条路径保证信件走哪条路线可以到达收件人的城市。网络接口层真正将信件交给邮车、快递员以电信号或无线信号的形式在物理介质里跑起来。1.2 协议族设计背后的三个核心思想TCP/IP协议族之所以能统治互联网几十年不是因为它的技术最完美而是因为它的设计哲学极其务实。搞懂这三点你就get到TCP/IP的灵魂了。第一端到端原则。网络只管把数据包尽量送到目的地至于数据对不对、顺序乱没乱、要不要重传那是通信两端的事情路由器等中间设备不做复杂的状态维护。这个原则带来的好处是网络的中间节点可以做得非常快、非常简单从而支撑大规模、高吞吐的转发。它也不是没有代价代价就是传输层得设计得足够健壮承载“可靠性”的重担。这就像快递公司只负责把包裹按时送到小区门口电梯坏了能不能搬上楼由你自己想办法。第二分层封装。每一层只需要处理自己这一层该处理的事情把复杂的通信问题拆解成若干个可独立解决的子问题。数据从应用层一路往下走每一层都会在数据前面加上自己的“头”这个过程叫封装到达对端后每一层再层层剥掉头这叫解封装。正是因为封装机制足够清晰应用层工程师写代码时根本不用关心数据是怎么通过海底光缆的网络层工程师也不用关心应用层到底传输的是网页还是视频。第三容错性设计。TCP/IP在设计时把网络状态设想为“不可靠的”比如IP层的路由器会丢包、会乱序、会重复以及更极端的网络路径可以随时变化。所有的可靠性保障都集中在TCP协议里来解决而不是在网络本身。这套思路放到今天依然不过时甚至可以说上面的应用层服务越做越复杂恰恰是因为底层网络的“尽力而为”承诺足够简单和稳定。1.3 协议族的主要成员一览TCP/IP协议族里的成员很多我给新人做培训的时候第一节课就会发一张协议全家福让大伙儿知道我们到底在学哪些东西。完整表格太长这里把最常碰到的核心协议整理一下。协议缩写全名所属层主要作用TCPTransmission Control Protocol传输层可靠、面向连接的字节流传输UDPUser Datagram Protocol传输层不可靠、无连接的数据报传输IPInternet Protocol网络层寻址和路由提供尽力而为的包投递ICMPInternet Control Message Protocol网络层差错报告与网络诊断ARPAddress Resolution Protocol网络接口层/网络层之间根据IP地址解析MAC地址DNSDomain Name System应用层域名与IP地址的互相转换DHCPDynamic Host Configuration Protocol应用层动态分配IP地址和网络配置HTTP/HTTPSHyperText Transfer Protocol (Secure)应用层网页和资源的传输FTPFile Transfer Protocol应用层文件传输SMTP/POP3/IMAP邮件相关协议应用层电子邮件的发送和接收Telnet/SSH远程登录协议应用层远程控制设备或服务器这个表不是让你背的而是让你在脑子里建起一张“地图”。以后你看到一个抓包文件或者阅读一份技术文档首先能判断出来这个协议属于哪一层、它干的是什么活儿再深入分析细节思路就会清晰很多。2. 核心协议细节解析与实操要点2.1 网络层IP协议到底做了什么IP协议是整个互联网的基石它的核心职责是两件事寻址和分片。寻址就是给每台接入网络的设备分配一个逻辑地址也就是IP地址。IPv4地址是32位二进制数习惯上写成点分十进制比如192.168.1.1。32位的地址空间大约能提供43亿个地址这在互联网早期绰绰有余但放到今天早就不够用了所以后来又推出了128位的IPv6。IPv6的地址空间大到可以给地球上每一粒沙子都分配一个IP地址短期之内不存在枯竭问题。我见过很多新手对IP地址的掩码理解不透。掩码Netmask的作用就是划清“网络号”和“主机号”的边界换句话说它告诉设备哪些IP和自己处于同一个网段通信不需要经过网关哪些IP在别的网段必须把包交给路由器。比如IP地址192.168.1.10和掩码255.255.255.0做按位与运算得到网络号192.168.1.0那主机号就是0.0.0.10。明白这一点对配置静态路由、排查跨网段通信问题非常有帮助。分片则是当数据包的大小超过链路层能够承载的最大传输单元MTU时IP层会把数据包拆成多个小片分别传输到了目的地再重新组装起来。传统以太网的MTU是1500字节这是以太网的“硬限制”。解决MTU问题最常见的法子有两种一是调小数据包的长度比如在TCP里通过MSS协商限制段大小二是开启路径MTU发现机制让沿途路由器用ICMP报文告知“这个包太大了”源端再调整。实操里我遇到最多的问题是“TCP数据包能发多大”。TCP层一般会根据路径MTU来协商MSS最大报文段长度通常用MTU减去IP头部和TCP头部的长度默认各20字节也就是1500减40等于1460字节。这个数值搞明白了你在分析抓包时经常看到的“Len: 1460”就有出处了。2.2 传输层TCP的三次握手与四次挥手你真的吃透了吗TCP是面向连接的、可靠的、基于字节流的传输协议。字面上每个词都是一个考点也都是工程中绕不开的坑。先说面向连接。TCP通信前必须建立一个连接这个建立过程就是著名的“三次握手”。客户端发送SYN报文seqx告诉服务器“我要建立连接”。服务器收到后回复SYNACK报文seqy并确认ackx1表示“我收到你的请求了我也要建立连接”。客户端再发送ACK报文acky1双方连接正式建立。三次握手的核心作用说白了就是“双方都确认自己发出去的包和对方发回来的包都能通”。有人说为什么不是两次握手因为只有两次握手的话当网络上滞留了老旧的连接请求会让服务器误以为是一个新连接傻乎乎地建立一条什么用都没有的链路白白浪费资源。加上了第三次握手服务器收到客户端回传的确认之后才能确定这个连接是客户端真实意愿的体现。再说可靠传输。TCP的可靠性依赖序号和确认号机制。发送方每发送一个数据段都会给它编上序号接收方收到数据后会返回一个确认号告诉发送方“我收到哪了下一个我希望收到的是哪一段”。如果发送方在一定时间内没有收到确认就会触发超时重传。这个机制在简单模型下很直观但实际网络里还存在两个极端情况接收方处理速度跟不上发送方的发送速度会通过滑动窗口机制来控制流量的发送速率。网络中同时有几条TCP连接在抢带宽TCP依靠拥塞控制算法慢启动、拥塞避免、快速重传等来动态调整发送速率。我在测试环境里经常通过抓包工具验证拥塞控制的触发过程。你会看到一段连接刚开始时被发送的数据段窗口非常小然后随着每次确认回来窗口指数增加这就是慢启动当出现丢包触发快速重传时窗口会断崖式下降然后再慢慢爬升。理解了这套机制你就明白了为什么长肥网络里TCP性能调试是一件很有技术含量的事情。TCP断开连接的四次挥手同样关键它要确保双方的数据都发送完了再拆链路。主动关闭方发送FIN报文表示“我没有数据要发了”。对端回复ACK表示“我收到了你的关闭请求”。对端发送FIN报文表示“我的数据也发完了可以关了吧”。主动关闭方回复ACK连接彻底释放。这里有一个常被忽略的技术细节TIME_WAIT状态。主动关闭方在最后一个ACK发出后并不会立刻释放连接而是会进入TIME_WAIT状态默认等待2个最大报文段生存时间2MSL。为什么要等这么久因为如果最后一个ACK丢失了对端会重发FIN如果主动关闭方提前把连接状态清理了就没人能回应这个FIN了。TIME_WAIT虽然占资源却是一个保证“旧连接的数据不会串到新连接里”的关键设计。2.3 UDP协议别只把它当成“TCP的备胎”很多教材在讲UDP的时候喜欢拿它跟TCP做对比给人的错觉是UDP一无是处。恰恰相反UDP在实时通信领域的地位是TCP完全撼动不了的。UDP是无连接的发送数据前不需要握手节省时延它没有重传机制数据丢了就丢了对于视频电话、语音通话、实时游戏来说扔一帧画面可以接受但为了重传而卡顿那是完全不能忍的。UDP的头部只有8字节而TCP头部至少20字节对于小数据包来说头部开销的比例差异非常明显。UDP在工程里的经典应用包括DNS查询、NTP时间同步、DHCP地址分配、流媒体传输、音视频通话以及近年来火得不行的大规模在线游戏。另外一个重要场景是QUIC协议它基于UDP实现目的就是绕开TCP协议栈在内核里的诸多限制把传输控制能力搬到用户态换取更好的连接建立速度和抗丢包能力。所以别再带着偏见看UDP了。选TCP还是UDP取决于你对可靠性、时延、连接状态这几个维度的权衡。传输层没有绝对的好协议只有适合场景的协议。2.4 网络接口层ARP协议最容易被人忽略的定时炸弹在TCP/IP四层模型里最底下的一层是网络接口层它负责在局域网内把IP数据包封装成链路层帧来发送。这里有一个协议是面试高频题实际排查网络问题也经常碰到就是ARP地址解析协议。ARP的作用是把IP地址解析成MAC地址。想象你在公司局域网里想访问一台打印机192.168.1.100你的电脑只知道它的IP不知道它的MAC地址那么在二层交换机转发帧时就不知道把数据从哪个物理端口送出去。于是你的电脑会在局域网里广播一条ARP请求“谁是192.168.1.100请把你的MAC地址告诉我。”目标设备收到后回复自己的MAC地址你的电脑再把IP和MAC的映射关系缓存起来。ARP协议看起来简单但工程中的坑一点都不少。经典的ARP欺骗就是靠向局域网内广播伪造的ARP响应把网关的流量引导到攻击者的机器上实现中间人攻击。即便在正常的网络里ARP缓存的过期、ARP条目过多导致的表项溢出都是日常运维中经常遇到的疑难杂症。我在企业网管时处理过一个癥状个别电脑偶尔断网排查半天最终发现是局域网里有人私设了小路由器导致ARP表项在内网互相“打架”。这种问题不学会抓包看ARP报文的话找起来相当烧脑。3. 实操过程与核心环节实现这一节咱们不看理论了直接上手。我用一套最常见的实操流程把它们串起来带着大家从零开始验证TCP/IP协议族的工作过程。环境假设是你自己有一台电脑装的是Windows、macOS或Linux都行然后能访问互联网。3.1 第一步用Ping验证网络层连通性打开终端敲下一条命令ping baidu.com这个命令背后的故事是你的电脑先通过DNS协议把baidu.com解析成IP地址然后向这个IP地址发送一个ICMP回显请求报文Echo Request如果目标主机回复Echo Reply说明从你到目标主机的网络层路径是通的。我自己在实际操作时习惯先ping网关再ping外网因为这样可以快速定位问题出在内网还是出在运营商链路。ping 192.168.1.1 ping baidu.com如果网关能通但外网不通重点是排查路由器NAT、上游链路、DNS配置等环节如果网关都不通问题大概率出现在自己的网卡配置、网线、交换机端或AP信号上。另外教你一个小技巧Windows上ping默认发4个包Linux上会一直发下去要手动按CtrlC终止。测试时建议加上-c参数Linux或-t参数Windows比如在Linux下运行ping -c 5 baidu.com限制发送5个包就够了避免一直刷屏。3.2 第二步用ipconfig/ifconfig查看网卡与IP配置要确认自己的网络参数Windows上运行ipconfig /allLinux上运行ipconfig # 有些新版本用 ip addr输出信息里重点看这几项IPv4地址网卡上的IP地址。子网掩码确认网络号和主机号的边界比如255.255.255.0。默认网关去往其他网段的下一跳设备地址。DNS服务器域名解析使用的服务器。物理地址MAC地址链路层用来二层通信的硬件地址。我曾经见过一个新人死活上不了网一查发现是IP地址和网关不在同一网段——电脑配的是192.168.1.10网关却填成192.168.2.1。这种问题的本质就是没理解掩码在网络层的作用。所以拿到一台新设备第一步永远是先确认网络配置再看其他。3.3 第三步用Tracert路径追踪看清数据包的“旅行路线”Windows下命令是tracert baidu.comLinux下是traceroute baidu.com这个命令的原理是发送一系列TTL生存时间值递增的IP报文。第一个包TTL1到达第一跳路由器后TTL减为0路由器丢弃包并返回ICMP超时消息源端记录下来这是第一跳接着发TTL2的包到第二跳以此类推。于是你能看到数据包从你家网关出发穿过一个个运营商路由器最后到达目标服务器的完整路径。路径追踪对排查“慢”的时候特别有用。如果发现延迟从某一跳开始猛涨大概率是那一跳的链路拥堵或线路跨地区转发。需要提醒的是很多骨干路由器出于安全考虑会禁止回应ICMP所以在tracert结果中看到* * *不要慌那不代表链路断了只是那一跳没有回复探查报文而已。3.4 第四步用Telnet或nc验证传输层端口连通性很多时候你需要确认目标主机的某个TCP端口是否对外开放这时候可以telnet 192.168.1.100 80如果端口开着屏幕会黑一下或出现一堆乱码然后进入空状态说明TCP连接已经建立成功。如果端口关闭会收到“Connection refused”之类的报错。Linux上更推荐用ncnc -vz 192.168.1.100 22-v表示输出详细信息-z表示只扫描端口不发送数据。这个方法比ping更能反映“应用服务是否正常”因为ping通只说明主机活着端口通不通还得看具体服务是否监听。3.5 第五步用抓包工具把协议“可视化”工具我推荐Wireshark免费、跨平台、功能强大。安装后选择一块网卡开始抓包然后触发一些网络动作比如打开网页、ping、访问一个FTP服务再停止抓包你会看到一条条结构化的协议记录。第一次用Wireshark的同学最容易懵的是不知道看什么。我的建议是先学会观察TCP三次握手过程第1条记录源端口是随机高位端口目的端口是80Flags字段显示SYN。第2条记录源目的端口对调Flags字段显示SYN、ACK。第3条记录Flags字段显示ACK。把这三条记录钉在你的脑海里以后分析任何HTTP通信问题都有了参照物。接着可以观察TCPSeq和Ack的数值变化判断有没有重传有没有乱序有没有重复ACK触发快速重传。这套技能在应用性能排查中不是加分项而是基本能力。4. 常见问题与排查技巧实录4.1 能上微信但打不开网页这个场景非常经典。微信、QQ这类应用可能用的IP直连或私有协议不需要域名解析而浏览器访问网站第一步就要做DNS解析。所以“能上微信打不开网页”里至少八成是DNS解析出了问题。排查思路先用nslookup baidu.com看能不能解析出IP地址。如果解析失败把DNS改成公共DNS比如223.5.5.5、114.114.114.114再试。如果解析成功但浏览器还是打不开可能是HTTP代理设置异常。我在实战中经常发现有些人电脑明明没设代理浏览器却莫名其妙走了代理导致访问异常。这种情况下检查IE或系统代理设置关掉代理或恢复自动检测就能解决。4.2 TCP连接超时但ping着通这个现象有迷惑性。目标主机“活着”但TCP层连接建立不起来通常原因有三类服务器防火墙拦截了源IP或目的端口表现为SYN发出去后石沉大海。服务器端口没有监听但这个服务器不回复RST而是直接丢弃这取决于防火墙策略。网络路径上有设备对特定端口做了访问控制。排查这个问题时我会在目标机器上做本地抓包确认SYN有没有到达网卡。如果到达了看应用进程有没有监听这个端口如果没到达把问题锁定在中间链路的过滤策略上。4.3 TCP三次握手一直不成功服务器高负载有人说“我访问某台服务器时非常慢抓包发现三次握手能成功但是HTTP响应特别迟。”这种情况多半不是TCP本身的问题而是服务端的应用进程在有限连接队列里排队太长。Linux的backlog机制决定了有多少TCP连接可以排队等待进程accept。当队列满了新来的连接会被操作系统暂缓或丢弃表现就是TCP握手成功了但应用层迟迟没有反应。这时候要检查服务器CPU、内存、应用日志必要时调大backlog或者优化应用处理并发的瓶颈。4.4 传输大文件慢无线网络为主因TCP的可靠传输依赖ACK确认无线网络本身误码率比有线高很多丢包明显增多一旦发生丢包就会触发拥塞控制窗口减半所以无线环境下的TCP传输经常出现“速度忽快忽慢”的情况。用户可能会把锅甩给Wi-Fi信号但本质上真的是TCP的可靠重传在无线环境下被放大了问题。对策一般有三个方向升级无线协议标准比如Wi-Fi 6减少同频干扰尽量用5GHz频段在应用层面考虑压缩传输减少网络负载。对TCP层来说Tune一些合理的buffer参数也能起到一定作用。4.5 解决MAC地址与IP地址“打架”局域网里两台设备配置了相同的IP地址这种IP地址冲突的现象在办公网里很常见现象是两台设备轮流掉线。排查办法登录交换机查看ARP表确认冲突IP对应的MAC地址。顺着MAC地址找对应交换机端口线缆拔掉后看哪台设备恢复。局域网内禁用非法的DHCP服务器防止有人私接路由器分配错误地址。处理完冲突之后强烈建议在核心交换机上配置DHCP Snooping它可以设置信任和不信任端口防止非法DHCP服务器和ARP欺骗报文在网络里胡作非为。这类安全机制是实际运维里的标配部署成本不高但能预防掉大量网络异常。5. 给学习者的路线建议与避坑指南5.1 不要试图一次吃透所有协议TCP/IP协议族涵盖的协议数量非常多一下子全部扎进去很容易被劝退。我给你一个务实的顺序先学核心三个IP、TCP、UDP。再学四个上层常用HTTP、DNS、DHCP、ARP。有余力再扩展ICMP、HTTPS、FTP、SMTP、SNMP、BGP、OSPF等。把核心三件套的原理吃透后面学什么协议都只是换了一层外衣底层套路是一样的。5.2 抓包是最好的老师理论学习再扎实没有抓包观察你对该协议的理解始终停留在纸面上。隧道可能说一万句不如抓一个包看得明明白白。我当年学TCP重传机制时就是自己搭了一个丢包率的测试环境用netem工具模拟网络抖动再抓包观察窗口变化那一刻才真正把课本知识和现实行为打通了。5.3 多动手做实验少纯背面试题很多人面试背八股文很溜真到现场解决实际问题时就抓瞎了。TCP/IP的学习必须配合动手实验例如用Wireshark抓三次握手、用tcpdump分析DNS请求、用scapy构造自定义包测试防火墙规则这些能力都是靠一遍遍折腾练出来的。没有实验设备的同学也不用担心可以用GNS3、EVE-NG这类模拟器搭建虚拟网络环境几乎零成本就可以复现绝大多数企业网络场景。5.4 避坑不要忽略MTU与路径最大传输单元MTU是我在实际中见过翻车最多的地方。许多隧道技术如PPTP、GRE、VXLAN会在原有数据包上额外增加头部导致数据包总尺寸超过1500字节进而产生分片或丢包表现为“网页时好时坏”“大包能通但小包不能下载”等奇葩故障。排查方法其实很简单用ping携带不同大小的负载测试路径MTUWindows上ping -f -l 1472 目标IP-f禁止分片-l指定负载长度。Linux上ping -M do -s 1472 目标IP。一旦发现某个数值忽然不通就找到了MTU瓶颈所在然后去调整隧道或网卡MTU值。这类问题排查思路清晰了解决起来很快思路不清晰会浪费一整天。我在最後再啰嗦一句TCP/IP这套东西是越用越熟、越学越透的。刚接触时觉得分层抽象难懂实际干活之后才会理解它的设计有多巧妙。千万别指望读一篇文章就能把协议族完全搞定拿上工具多抓几个包多踩几个坑再把今天这篇文章里的排查思路套进去你的网络功底自然就扎实了。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进