ARTICLE DETAIL

资讯详情

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

TCP/IP协议栈实用指南:分层原理、封装流程与Windows发包收包验证

TCP/IP协议栈实用指南:分层原理、封装流程与Windows发包收包验证 干网络这行TCP/IP 协议栈是绕不开的基础。不管是排查一台上不了网的电脑还是定位两台服务器之间的吞吐瓶颈最终都要回到这四层模型上来重新捋一遍。这篇文章我想从实际使用的角度把 TCP/IP 模型里每一层到底干什么、数据是怎么一层层包进去再拆出来的、以及 Windows 系统上怎么做端到端的发包收包验证一次性讲清楚。适合刚入行的网工、运维也适合写网络应用的开发同学——你跟别人联调接口对不上时很多时候不是代码问题而是跨层参数没对上。1. 不是背公式先把 TCP/IP 当成一个快递系统来理解1.1 为什么需要分层这样设计很多人一上来就背“应用层、传输层、网络层、网络接口层”背完就忘因为不知道这套分层设计到底要解决什么问题。其实分层这件事和你在快递站寄包裹是同一个逻辑你和快递员各管一段彼此不需要懂对方手里的全部细节。寄快递时你要做三件事把东西装进箱子内容在面单上写清楚寄件人和收件人的姓名、电话传输层的端口再写清楚省市区街道门牌网络层的 IP 地址。而快递公司负责安排卡车、飞机把包裹从A地运到B地网络接口层。每一层只关心自己的那点事中间某一段换运输方式比如从陆运转空运你的面单和箱子内容完全不用变。TCP/IP 分层也是这个道理。应用层只关心“我说的是什么”HTTP 也好、DNS 也好它不关心数据怎么走网线传输层关心“谁发给谁”通过端口号区分不同的应用进程网络层关心“去哪个网段”通过 IP 地址做路由网络接口层关心“在物理链路上怎么传给下一跳”通过 MAC 地址和以太网帧完成收发。四层各有职责替换任何一层都不影响其他层这就是它能活几十年的核心原因。1.2 四层模型和七层模型的实际取舍老网书会提 OSI 七层模型物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。TCP/IP 模型简化成四层工程排错时也基本按这个缩略版来。实际工作中没人会先分析“会话层出了问题”你说出这种话旁边老师傅大概率只是让你先 ping 一下。OSI 七层和 TCP/IP 四层的对应关系可以看这个简表OSI 七层TCP/IP 四层典型协议/技术应用层、表示层、会话层应用层HTTP、HTTPS、DNS、SSH、FTP传输层传输层TCP、UDP网络层网络层IP、ICMP、ARPARP 严格算在链路层之上常被归到网络层附近数据链路层、物理层网络接口层以太网、Wi-Fi、MAC 地址、网卡驱动实际排障时四层模型已经够用。你在浏览器里看到“无法访问此网站”心里应该立刻按层过一遍DNS 解析有没有结果TCP 三次握手有没有成功中间路由能不能通最后才是服务器应用层状态。这套思路就是分层带来的好处。2. 逐层拆解 TCP/IP 模型每一层到底在干什么2.1 应用层只负责“说什么”不负责“怎么送”应用层是离用户最近的一层也是大家最熟悉的一层。浏览器里的 HTTP 请求、发邮件用的 SMTP、查域名用的 DNS都属于应用层协议。这一层核心任务是把用户的操作转换成“标准格式的数据”至于这些数据是被 TCP 可靠送达还是被 UDP 丢了重发应用层不太关心——那是下面两层的事。这里有个常见误解端口号明明是写在数据包里的为什么算传输层概念因为端口号确实由 TCP/UDP 头携带。但应用层在“用哪个端口”这件事上有绝对话语权HTTP 默认 80HTTPS 默认 443DNS 默认 53。你可以理解成传输层提供 65535 个门牌号应用层决定把哪封信放到哪个门牌下。Socket 就是 IP 地址加端口号的组合一个“小区定位 门牌号定位”网络世界里的进程通信全靠这对组合。应用层的排障最常见的就是 DNS 问题。你在浏览器里输入一个域名系统先去问 DNS 服务器这个域名对应哪个 IP如果这一步卡住浏览器表现就是“转圈半天然后报错”但此时网络本身可能完全正常。所以判断应用层故障前先确认一下域名解析是否成功这事一句话就能完成nslookup www.example.com。2.2 传输层端口、序列号和可靠传输的真正起点传输层是 TCP/IP 协议栈里最“有故事”的一层。TCP 和 UDP 是两种完全不同的思路打个比方TCP 是挂号信每一封都要收件人签字回执丢了要补发顺序乱了要重排UDP 是明信片写完扔进邮筒就不管了能不能到、先到后到全看运气。TCP 的可靠性不是靠“多转发几次”实现的而是靠一套精心设计的机制建立连接要三次握手传输数据每个字节都有序号收方要回 ACK 确认发送方有超时重传和快速重传还有滑动窗口控制发送速度。三次握手的三个包特别直观客户端发 SYN 包请求建立连接服务端回 SYNACK收到请求且同意建立客户端再回 ACK确认收到服务端的确认。为什么不是两次因为要确认双方收发能力都正常。一次握手只证明“客户端能发服务端能收”三次才能证明双方“既能收也能发”这套逻辑想通了后面看抓包时就不会把 SYN 重传误判成攻击。UDP 就好办多了没有握手、没有序号、没有确认包头只有源端口、目的端口、长度和校验和。优点是开销小、延迟低适合音视频通话、在线游戏这种“旧一点没关系卡顿才致命”的场景。DNS 查询也用 UDP因为每个查询就几个字节不值得为它建立一条 TCP 连接。传输层排障要看两个核心指标端口是否监听连接是否建立。Windows 上一条命令就能看netstat -ano。如果端口没在监听问题大概率是服务没起来如果在监听却连不上要么防火墙挡了要么服务绑定的地址不对。2.3 网络层IP 地址、路由与分片处理网络层解决的是“数据包怎么从源主机到目标主机”的全局路径问题。IP 协议负责编址和路由ICMP 负责网络层诊断。你 ping 一个地址用的就是 ICMP 协议它和 TCP 不是一回事——很多人说“能 ping 通就说明网络没问题”严格说只代表 IP 层可达不代表 TCP 端口可用。IP 包头里值得关注的字段有这几个源 IP、目的 IP、TTL、协议号、标识和片偏移。TTL 是“生存时间”每经过一个路由器减 1减到 0 就被丢弃防止数据包在网络里无限兜圈。Windows 默认 TTL 是 128Linux 默认是 64你 tracert 时看到的每一跳就是在看 TTL 递减的过程。协议号则告诉接收方“这个 IP 包里面装的是 TCP 还是 UDP”TCP 是 6UDP 是 17。路由和分片是网络层的两个重头戏。同一网段内通信主机直接用 ARP 查对方 MAC 地址然后封装成以太网帧发出去跨网段通信主机把包交给默认网关由路由器一级一级转。这里有个容易忽略的点以太网帧的最大长度是 1518 字节去掉帧头帧尾后IP 包最大 1500 字节这就是 MTU。如果上层数据太大IP 层就要分片。但分片会带来性能问题——一个片丢了整包都废了所以现代 TCP 干脆在握手时就协商好分段大小让 IP 层少干活。TCP 的 MSS 默认就是 1460 字节也就是 1500 减去 20 字节 IP 头再减去 20 字节 TCP 头这样正好塞进一个标准以太网帧不需要 IP 分片。2.4 网络接口层从帧到比特的最后一百米网络接口层是 TCP/IP 模型里最“接地气”的一层它负责把 IP 包变成能在网线上跑的以太网帧再从网线上把比特收回来。这一层核心有两个东西MAC 地址和以太网帧格式。MAC 地址是网卡的物理地址48 位出厂时烧录理论上全球唯一。IP 地址描述“逻辑位置”MAC 地址描述“物理身份”两者通过 ARP 协议互相映射。主机要发数据给同网段另一台主机时先查自己的 ARP 缓存没有就广播一条“谁是 192.168.1.100请把你的 MAC 告诉我”目标主机回复后源主机把 IP 和 MAC 的对应关系缓存下来一般缓存几分钟到几小时。以太网帧的格式值得扫一眼目的 MAC6 字节 源 MAC6 字节 类型2 字节 数据46~1500 字节 帧校验4 字节。交换机转发数据就是靠查帧里的目的 MAC 地址维护一张 MAC 地址表也叫 CAM 表。这块和路由的概念容易混淆路由器根据 IP 地址选路然后改写 MAC 地址把帧从对应端口发出去交换机只认 MAC不做跨网段路由。3. 数据在 TCP/IP 模型中传输的完整旅程3.1 一次 HTTP 请求从输入到封装的全程把理论落到实际最直观的案例就是浏览器访问一个网页。假设你输入http://192.168.1.10/index.html这里省略 DNS 解析直接用 IP数据包的旅程是这样的应用层把GET /index.html HTTP/1.1这个请求按 HTTP 格式组织好交给传输层。传输层TCP给这段数据加上 20 字节 TCP 头包含源端口随机高位端口比如 50000、目的端口80、序列号、ACK 号、窗口大小等形成 TCP 段。网络层IP再给 TCP 段加上 20 字节 IP 头包含源 IP你的本机 IP、目的 IP192.168.1.10、TTL、协议号 6形成 IP 包。网络接口层给 IP 包加上 14 字节以太网帧头目的 MAC、源 MAC 和类型字段和 4 字节帧校验形成以太网帧从网卡发出去。这个过程画成表格更清楚阶段数据形态增加的头部关键字段应用层处理完HTTP 请求数据无应用层协议头算在数据里GET 请求行、Header、Body传输层封装后TCP 段TCP 头 20 字节源端口 50000、目的端口 80、SEQ、ACK、Window网络层封装后IP 包IP 头 20 字节源 IP、目的 IP、TTL128、协议号6网络接口层封装后以太网帧帧头 14 字节 帧尾 4 字节目的 MAC、源 MAC、类型 0x0800发出去之前TCP 还要先完成三次握手确保服务端 80 端口是开的。所以你在抓包里看到的顺序是先有 SYN、SYN-ACK、ACK 三个握手包然后才是那个GET /index.html的数据包。3.2 链路上交换机、路由器的转发与解封装以太网帧从你的网卡出来后第一站是交换机。交换机收到帧只关心目的 MAC 地址在自己的 MAC 地址表里查查到就单播转发到对应端口查不到就广播到所有端口除了接收口。交换机全程不碰 IP 头和 TCP 头所以交换机不关心你访问的是哪个 IP、哪个端口——这也是为什么交换机配置里看不到“路由”两个字。如果目标主机在另一个网段帧会先到达你的默认网关路由器。路由器收到帧后拆掉以太网帧头露出 IP 包查看目的 IP在自己的路由表里找到下一跳出口然后把 IP 包重新封装成新的以太网帧——注意源 MAC 会改成路由器出口端口的 MAC目的 MAC 会改成下一跳设备的 MAC但源 IP 和目的 IP 始终不变。这就是“路由改 MAC 不改 IP”的口诀来源。到达目标主机后解封装是从下往上的逆过程网卡收到帧去掉帧头帧尾交给 IP 层IP 层看目的 IP 是不是自己是就去掉 IP 头交给 TCP 层TCP 层校验序列号把数据按序组装好交给应用层。整个过程有几次头部移除数据本体一直没变。理解这套流程后你就明白为什么抓包时看到 “TCP Retransmission” 不一定是丢包——也可能是接收方的 TCP 缓冲被占满被迫丢弃后续数据。3.3 可靠传输背后的确认和重传机制TCP 的可靠性建立在“序号 确认 重传”这个三角关系上。发送方给每个字节编号比如发送 1000 字节序号从 1 到 1000接收方收到后回一个 ACK这个 ACK 号表示“我期待下一个字节的序号”也就是 1001。如果发送方在超时时间内没收到 ACK就把这段数据重发一次。更高效的重传是快速重传如果接收方收到一个乱序的包比如期望序号 1001却收到了序号 2001 的数据它会立刻回一个 ACK1001确认序号不变表示“我还在等 1001”。发送方连续收到三个相同的 ACK1001不用等超时立刻重发序号 1001 的数据。这就是抓包里看 DUP ACK 的含义。滑动窗口则解决了“发多快”的问题。接收方在 TCP 头里通告自己的接收窗口Window告诉发送方“你最多可以给我发这么多字节不用等确认”。如果接收方处理不过来窗口就会变小发送方就自动放慢速度。这就是 TCP 的流控——它不靠暴力限速而是靠对端反馈动态调整。理解了这几个机制再去看 Wireshark 里那些 Expert Info 提示至少能分清“这是丢包导致的重传还是乱序导致的确认异常”。4. Windows 系统下端到端 TCP/IP 发包收包实测4.1 Windows 自带的网络诊断工具使用清单Windows 系统里其实藏着一整套 TCP/IP 排障工具只是很多人只知道 ping。这里列一份我平时用得最频繁的工具清单每个工具解决一个层面的问题工具作用层面典型命令适用场景ipconfig网络层/IP 配置ipconfig /all查看 IP、子网掩码、网关、DNS、MAC 地址ping网络层/ICMPping -t 192.168.1.1测试到目标是否连通、延迟多大tracert网络层/路由路径tracert www.example.com定位卡在哪一跳查看路由是否走错pathping网络层链路质量pathping 192.168.1.1统计每一跳的丢包率比 tracert 更详细route print网络层/路由表route print -4查看默认路由是否正确、有没有多余路由netstat传输层/端口状态netstat -ano查看端口监听状态定位 PID 对应的进程Test-NetConnectionPowerShell 全能测试Test-NetConnection 192.168.1.10 -Port 80相当于集成版 telnet测试 TCP 端口是否能通getmac链路层getmac /v查看本机各网卡的 MAC 地址重点说下Test-NetConnection如果你在用 PowerShell 的话这个命令效率极高。Test-NetConnection www.baidu.com -Port 443会同时返回 DNS 解析结果、目标 IP、Ping 结果和指定端口的 TCP 连接测试结果不用再一个一个敲命令拼信息。4.2 用 iperf 实测两台 Windows 主机的收发吞吐ping 只能测到目标能不能通但测不出网络的真实吞吐能力。想确认两台机器之间的 TCP/IP 传输实际能达到多大带宽标准做法是用 iperf 打流。先准备两台 Windows 机器一台当服务器一台当客户端。iperf3 的 Windows 版本从官网下载解压就行是个免安装的 exe 文件不需要额外安装依赖。服务端执行iperf3.exe -s -p 5201-s表示服务端模式-p 5201指定监听端口。客户端执行iperf3.exe -c 192.168.1.10 -t 60 -i 5 -P 4-c后面跟服务端 IP-t 60表示测试 60 秒-i 5表示每 5 秒打印一次结果-P 4表示用 4 个并行连接同时打流能把多核网卡的吞吐潜力压出来。跑完客户端会显示每个连接的平均带宽和汇总值。这里有几个实测中容易踩的坑。第一Windows 防火墙默认会拦截 iperf 的 5201 端口服务端需要提前放行netsh advfirewall firewall add rule nameiperf dirin actionallow protocolTCP localport5201。第二iperf3 和 iperf2 协议不兼容两台机器必须用同一个大版本否则客户端连接后看不到任何数据。第三测吞吐前先确认两端网卡的协商速率任务管理器—性能—以太网里看链接速度如果显示 100 Mbps 而不是 1 Gbps问题多半在网线或交换机端口不是 TCP/IP 参数的问题。一次正常千兆测试的预期结果大约是 900 Mbps 到 940 Mbps 左右这是 TCP 协议开销的物理上限。如果测出来只有 5 Mbps且测试输出里出现大量重试那就要借助抓包来看丢包到底发生在哪一段了。4.3 用 Wireshark 抓包验证 TCP 三次握手和捭包过程Windows 下抓包工具首推 Wireshark配 Npcap 抓包驱动。安装完成后打开 Wireshark选择上网的那块网卡名字一般是“以太网”或“WLAN”点击开始捕获然后去浏览器访问一次目标网站就能看到一串 TCP 包。先在过滤栏输入tcp.port 80过滤出 HTTP 流量再输入tcp.flags.syn 1过滤出 SYN 包就能清晰看到三次握手的三个包第一次是本地 IP 发往服务器 IP标志位 SYN序列号是一个随机初始值第二次是服务器回包标志位 SYNACK序列号是服务器的随机值ACK 号是客户端的初始序列号加 1第三次是客户端回 ACK序列号是客户端初始号加 1ACK 号是服务器初始号加 1。看序列号的变化是理解 TCP 的关键。初始序列号看起来毫无规律是因为现代 TCP 栈做了随机化防止老连接的数据包污染新连接这属于正常设计用不着觉得奇怪。抓包时还会看到一些红色标注的 “TCP Retransmission” 或 “TCP Out-of-Order”新手会慌其实先看上下文再下结论一个重传包出现要看它前面是不是丢了 ACK还是这个包本身真的丢了配合 TCP 的 StreamGraph统计—TCP 流图—时间序列图能直观看出丢包点。抓本机回环流量比如访问本机部署的网站时有个小坑Windows 上 Npcap 默认能抓回环但需要在 Wireshark 里选“Npcap Loopback Adapter”或“Adapter for loopback traffic capture”这个虚拟接口而不是“以太网”接口。选错了会看到接口列表里根本没有你的回环流量。5. 常见问题与排查技巧实录5.1 高频故障排查速查表结合前面的内容把日常遇到最多的几类问题整理成一张速查表照着顺序查就够现象检查顺序常用命令常见根因完全上不了网网卡状态 → IP 配置 → 网关 → DNSipconfig /all、ping 网关、ping 8.8.8.8DHCP 获取失败、网线松动、网关宕机能 ping 通 IP但访问不了域名DNS 解析nslookup www.example.comDNS 服务器不可用、DNS 缓存污染能上微信/QQ但网页打不开TCP 80/443 端口、HTTP 代理Test-NetConnection www.example.com -Port 80代理设置有问题、防火墙封了网页端口局域网内互相 ping 不通ARP、VLAN、防火墙arp -a、ping 同网段IPWindows 防火墙开了“阻止所有传入连接”延迟忽高忽低链路质量、无线信号pathping 目标IPWi-Fi 干扰、网线质量差、广播风暴下载速度远低于带宽TCP 窗口、网卡协商iperf3 打流、任务管理器看链接速度网线只通了 4 芯、路由限速、NAT 性能瓶颈5.2 几个容易误解的 TCP/IP 细节第一“能 ping 通”不等于“能建立 TCP 连接”。ping 走的是 ICMP服务端即使不运行任何服务比如 80 端口没监听也会正常回 ICMP。判断服务是否可用必须测 TCP 端口用Test-NetConnection比用 ping 靠谱得多。第二“看到 TCP Retransmission”不等于“网线断了”。重传是 TCP 的自我修复机制和丢包率相关。阈值的经验值是千兆链路打流时重传率低于 0.1% 属于正常如果超过 0.5%就要看是不是网卡驱动开了太多中断合并导致缓冲溢出或者链路本身有误码。第三“回环 ping 通”只说明协议栈没问题。ping 127.0.0.1的数据包根本不经过网卡和物理链路它验证的是从应用层到网络接口层的 IP 协议栈是否被正确加载。它在 Windows 上如果失败了一般意味着 TCP/IP 栈损坏可以尝试用netsh int ip reset重置但别把它当成网络连通性的证明。第四防火墙的状态影响容易被忽略。Windows 防火墙在默认配置下允许出站流量但服务器场景里如果改成“阻止所有传入连接”即使服务本身在监听外部也无法访问。排障到这一步时优先检查防火墙再检查代码能省下大量时间。5.3 抓包和打流实验的个人经验心得我做过的 TCP/IP 实测里最有价值的一件事就是把 Windows 本机、一台交换机和一台 Linux 服务器串起来跑通“ping 网关 → ping 服务器 IP → iperf 双向打流 → 抓包看三次握手”这条完整链条。整个过程下来对分层模型的理解比看了十遍书都深刻。抓包时我一般遵守三条个人原则。第一先用捕获过滤器圈定范围比如只抓特定主机host 192.168.1.10或特定端口tcp port 5201因为大流量环境全量抓包会把磁盘写满也会让 Wireshark 卡成幻灯片。第二先看 TCP 错误标记比如 Expert Info 里的黑底红字项目再顺着时间线看上下文最后才看数据内容顺序反了容易被大量正常流量淹没。第三分析吞吐问题时除了看重传还要看 TCP Window 有没有被打满如果窗口一直很小说明接收方处理能力是瓶颈这时候调发送端参数没用。iperf 打流测出来的数字也不是绝对的。网络设备上的 QoS 策略、交换机单端口限速、甚至 Windows 的接收侧缩放RSS配置都会影响结果。建议多测几轮先用-P 1测单连接再-P 4测多连接对比数据比单次结果更有参考价值。最后再分享一个小技巧。Windows 内置了netsh trace一条命令就能启动系统级网络跟踪同时抓取事件追踪日志和网络数据包比单独配 Wireshark 在有些场景下更省事。排查周期性网络问题而不想一直挂机抓包时可以试试netsh trace start captureyes问题复现完netsh trace stop生成的文件可以用 Wireshark 打开里面的抓包视图和事件日志是联动的能省去很多从协议栈和系统日志两头找线索的功夫。TCP/IP 这套东西说复杂也复杂说简单也简单。复杂的是它几十年累积下来的细节比如拥塞控制算法就有 Reno、Cubic、BBR 一堆变体简单的是它的分层思想——每一层只干自己该干的活层与层之间通过标准接口协作。你不需要把所有细节都背下来但你需要亲手抓一次包亲眼看着三个握手包在 Wireshark 里依次出现然后顺着数据包一层层拆下去。做完这件事那些抽象的概念就有了实际的锚点以后再遇到网络问题心里不会慌。
返回列表