
简介面向网络开发、运维及协议调试人员的TCPUDP测试工具资源覆盖从传输层原理理解到工具实操的完整路径可用于模拟服务端与客户端通信、收发数据包、计算丢包率和延迟并快速定位网络故障。压缩包共14个文件体积约1.5MB以可执行程序exe为核心辅以配置文件ini、说明文档txt和界面截图jpg开箱即用参数可按需调整。目前已有2889人学习下载适合刚接触TCP/UDP的初学者也适合需要日常网络调试的工程师。资源内置TCPUDPDbg.exe主程序及配套组件除基础的数据包发送与接收外还支持端口扫描、流量观测、压力测试等操作配合附带的配置与说明文件可直观对比TCP的可靠传输与UDP的低延迟特性用于教学演示、协议实验或实际排障都非常实用。1. 一个可靠的 TCP/UDP 测试工具能帮你省掉多少排查时间做网络调试的人几乎都经历过这种阶段服务端说连不上客户端说发过了两边对着截图吵最后发现是报文格式差了半个字节。TCPUDP测试工具这个方向解决的就是这个黑匣子问题——把连接、收发、带宽、丢包全部变成你能直接看到的东西。无论你是嵌入式工程师在调 ESP01S 的 TCP 透传还是后端在排查 Harbor 推送镜像时 dial tcp 超时手里有一套趁手的 TCP/UDP 测试工具定位问题的速度能差出好几倍。这篇文章不讲虚的直接按「选型 → TCP 实测 → UDP 打流 → 避坑 → 脚本化」这条路径走。新手能照着命令一步步复现熟手可以直接跳到第 5 章的排错清单。工具都是常见的 nc、ncat、iperf3、Wireshark、socat 这一类不依赖特定平台Windows、Linux、macOS 都能跑。2. 选型先于动手四类 TCP/UDP 测试工具怎么挑很多人的误区是先装一个网络调试助手然后发现它只支持 TCP Server 和 UDP 收发等你要测吞吐、要构造畸形报文、要脚本化回归时又得换工具。我一般会把工具按用途分成四类先想清楚这一轮要解决什么问题再决定用哪个。2.1 命令行派nc / ncat / socat 的适用边界ncnetcat是最经典的 TCP/UDP 瑞士军刀适合做连通性探测和简单收发。Linux 发行版自带的通常是 OpenBSD 版功能够用Windows 10 以后的系统也内置了 nc 的替代品只是名字和参数略有差异。ncat 是 Nmap 项目维护的增强版支持 SSL、代理、连接保活写自动化脚本更稳。socat 则强在端口转发和双向数据桥接比如把串口数据桥到 TCP或者做 UDP 中继。我自己的分工是纯连通性测试用 nc需要可靠退出码和重试逻辑用 ncat涉及数据格式转换和转发用 socat。这三个工具都能在脚本里用这是 GUI 工具比不了的。注意一点nc 在不同发行版上参数差异不小-q、-z、-v这些选项在 OpenBSD 版和传统版里行为不一样跨机器执行时尽量先用nc -h确认版本。2.2 GUI 派网络调试助手、Wireshark、Postman 的定位GUI 工具适合两种场景一是你刚接触网络调试需要可视化地看到连接状态和收发内容二是你要分析协议细节比如 TLS 握手过程、TCP 重传。常见做法是先用网络调试助手这一类工具做手工联调把服务端的 IP、端口、报文格式确认好再交给自动化脚本去回归。Wireshark 不算测试工具它是排错工具。它能抓到网卡上真实经过的包能看到 TCP 三次握手、重传、零窗口、RST 这些底层行为。很多「工具显示发送成功但服务端没反应」的问题最终都是靠 Wireshark 抓包才定位的。Postman 主要测 HTTP 层如果你要测的是 Modbus TCP、私有协议、裸 TCP 长连接Postman 帮不上忙别浪费时间。2.3 打流派iperf3 与吞吐测试的选型理由当你需要验证两台机器之间的实际带宽、抖动和丢包率时nc 就不够用了。iperf3 是行业里做吞吐测试的事实标准它的 UDP 模式能指定带宽、包大小、测试时长输出包含丢包率、抖动和带宽三个核心指标。TCP 模式则能测出在默认拥塞控制算法下的实际吞吐。选它的理由有三个第一客户端和服务端是同一套二进制不用纠结协议兼容第二输出结果结构化有 JSON 格式可选方便脚本解析第三支持反向测试-R和双向测试-d能一次性暴露不对称链路的问题。注意 iperf3 和 iperf2 的兼容性不好两端尽量都用 iperf3 同版本附近跨大版本经常握手失败。2.4 选型对照表与我的默认组合测试目标首选工具备选关键参数TCP 连通性探测nc / ncattelnet-z -v -wTCP/UDP 报文收发ncat / socat网络调试助手-C / -u吞吐、抖动、丢包iperf3iperf2-u -b -t -l协议细节与重传分析Wiresharktcpdump过滤器 统计自动化回归脚本ncat bash/pythonsocat退出码 超时这套组合覆盖了我日常 90% 以上的测试场景。GUI 工具不是不用而是只在手工联调阶段用一旦进入重复验证环节脚本一定比手点快。3. 用 nc 和 ncat 做 TCP 测试从单发报文到并发压测TCP 测试的核心动作就三个建立连接、发数据、断开。但真正做起来会发现连接建立只是第一步后面的报文格式、粘包、服务端处理能力才是大头。这一章按难度递增给你一套可以直接抄的 TCP 测试流程。3.1 最小可用监听、连接、发一句话先在最简单的层面跑通收发。在一台机器上监听 9000 端口在另一台机器上连接并发送字符串。Linux 下监听端用# 监听 TCP 9000-k 保持监听-v 打印连接信息 nc -k -v -l 9000客户端发送# 连接目标 192.168.1.100 的 9000 端口发送 Hello 后等待响应 echo Hello | nc -v -w 3 192.168.1.100 9000这里的逻辑是服务端先挂起监听客户端连接后把标准输入的字符串发过去。-w 3表示连接或接收数据最多等 3 秒超过就退出。注意-k参数很关键没有它客户端一断开监听进程就退出了。做服务端模拟时务必要加。如果你用 ncat监听端更稳定断线后不会退出# ncat 监听-k 保持监听-c 每条连接执行一次命令 ncat -k -v -l 9000参数说明-l监听模式-v输出详细信息-k接受多次连接。-c参数可以用来在每条连接建立时执行一段脚本这个在伪造服务端响应时非常有用比如自动回复固定报文。3.2 模拟 HTTP 和 Modbus TCP 报文十六进制收发很多私有协议不是纯文本比如 Modbus TCP 的报文是十六进制字节流。nc 默认按文本处理遇到二进制就要用十六进制转换。我常用的做法是把报文写入文件用管道交给 nc或者在 nc 中直接使用\x转义ncat 支持--send-only配合 hex 字符串。发送 Modbus TCP 读保持寄存器请求的示例# 构造 Modbus TCP 请求帧发送到 502 端口 # 00 01 为事务标识00 00 为协议标识00 06 为长度01 为单元号03 为读保持寄存器 printf \x00\x01\x00\x00\x00\x06\x01\x03\x00\x00\x00\x0a | ncat -v -w 5 192.168.1.50 502这里的关键是把帧的六个部分拆开理解事务标识 协议标识 长度 单元号 功能码 数据。调试时如果服务端没响应先用 Wireshark 抓包确认请求帧是否完整到达再对照服务端日志查功能码处理。-w 5是收包超时很多 TCP 调试工具默认无限等待脚本里务必加超时否则卡住整个流程。3.3 并发连接和重复重连暴露服务端资源泄漏单连接测试过了只能证明链路通。服务端能不能扛住几十个并发连接断开后有没有回收资源这些得用并发压测暴露。常见做法是用 ncat 配合 shell 循环或者直接用 Python 的 socket 写一个压测脚本。这里给一个 Python 的最小并发连接测试import socket import threading import time results [] def try_connect(ip, port, timeout3): try: s socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(timeout) s.connect((ip, port)) s.send(bping) data s.recv(1024) s.close() results.append((True, data)) except Exception as e: results.append((False, str(e))) # 并发 100 个连接每个独立线程 threads [threading.Thread(targettry_connect, args(192.168.1.100, 9000)) for _ in range(100)] for t in threads: t.start() for t in threads: t.join() succeed sum(1 for r in results if r[0]) print(fsucceed: {succeed}/{len(results)}) print(ffailed samples: {[r[1] for r in results if not r[0]][:3]})这个脚本的核心价值不是测吞吐而是测「服务端能不能同时维持这么多连接」。如果 succeed 远低于 100先看服务端的最大连接数限制、文件描述符限制、半连接队列大小。如果 succeed 是 100 但随后服务端挂掉大概率是资源泄漏。sock.settimeout(3)很重要不加它会卡死在 connect 上。3.4 TCP 连接排错timestamps、端口占用、半开连接TCP 连接失败时不要只看「连不上」三个字。先用ss -t -a看目标端口有没有监听再用ss -t -a -n看当前连接状态是 ESTAB 还是 SYN_SENT。SYN_SENT 一直不变说明 SYN 包发出去没回来多半是防火墙 drop 或网络不通。如果是 ESTAB 但收不到数据再看 TCP timestamps 和窗口大小。Windows 上有个名场面netsh int tcp set global timestampsenabled开启 TCP 时间戳后某些 NAT 环境下的连接会频繁被 RST。时间戳本身是 RFC 7323 的标准能力但中间设备对它的处理不一致。遇到诡异断连先执行netsh int tcp show global看当前状态再决定要不要关掉。Linux 下对应的参数是net.ipv4.tcp_timestamps默认开启一般不用动。4. UDP 测试为什么难用 iperf3 打流与丢包定位UDP 无连接没有握手没有确认所以「测试成功」的定义很模糊——发出去了算成功还是对方收到算成功这就是 UDP 测试比 TCP 麻烦的地方。TCP 测的是通不通UDP 测的是丢多少、乱多少、延迟多少。4.1 UDP 无连接先把「测什么」定清楚动手之前先回答三个问题第一你要测的是单包收发还是持续数据流第二对端是否真的在监听第三丢包率、抖动、乱序哪个指标是这次测试的重点。单包收发测试用 nc 最简单。服务端监听 UDP 端口客户端发一句话看服务端能不能收到# 监听 UDP 9000 端口 nc -u -v -l 9000# 发送 UDP 包到目标端口 echo udp test | nc -u -v -w 1 192.168.1.100 9000注意-u参数没有它 nc 默认走 TCP。UDP 模式下-w 1的含义是等待响应的超时而不是连接超时——UDP 没有连接所以这个参数经常让人困惑。如果对端没有转发响应nc 会在超时后退出哪怕包已经发出去了。4.2 iperf3 UDP 打流带宽、抖动、丢包的参数组合要测链路质量单包不够必须打流。iperf3 的 UDP 模式是我最常用的工具。服务端先起来# 服务端监听默认 5201 端口 iperf3 -s客户端打流# 以 10Mbps 速率打流 30 秒UDP 模式包大小 1400 字节 iperf3 -u -c 192.168.1.100 -b 10M -t 30 -l 1400输出里最关键的三个指标是lost/total datagrams的丢包率、jitter抖动、out-of-order乱序数。参数说明-b 10M是目标带宽UDP 模式不设带宽会默认按 1Mbps 发导致结果失真-l 1400是 UDP 包负载大小默认 1470 接近 MTU 上限网络设备分片策略会影响结果建议按业务实际包大小去设置。有个容易被忽略的点-b设置的带宽是「发送速率」不是「期望吞吐」。如果你设 100M但实际链路只有 50Miperf3 会按 100M 的速度发送并统计出大约 50% 的丢包。这是正常的它测的就是链路在指定发送速率下的承受能力。想测链路极限带宽需要用二分法不断调高-b直到丢包率超过 1% 为止。4.3 组播与广播socat 收发的注意事项工业场景里经常遇到 UDP 组播比如电力、楼宇自控系统。组播测试不能用 nc 直接发单播的方式得用 socat 或者专门的组播工具。socat 接收组播的典型写法# 接收组播地址 239.1.1.1 的 5000 端口数据 socat -u UDP4-RECVFROM:5000,ip-add-membership239.1.1.1:0.0.0.0 -发送端# 发送组播数据到 239.1.1.1:5000 echo mcast | socat - UDP4-DATAGRAM:239.1.1.1:5000,so-broadcast这里有两个高频踩坑点。第一个是ip-add-membership参数它决定了网卡加入哪个组播组IP 地址写错会导致收不到任何包。第二个是路由器对组播的 TTL 限制默认 TTL 为 1跨网段需要加大 TTLsocat 里用,so-ttl2设置。如果你发现本机收得到、跨机器收不到先查 TTL 和中间交换机 IGMP 配置。4.4 用 Wireshark 确认 UDP 到底到没到当 iperf3 显示丢包而双方都觉得自己没问题时用 Wireshark 抓包看真实到达情况。抓包过滤器推荐udp.port 9000 ip.addr 192.168.1.100重点看三列Source、Destination、Sequence。UDP 没有序列号但 iperf3 会在 UDP 载荷里自带序列号。你要确认的是发端发出的包序号在抓包里是否连续收端抓到的包序号是否和发端抓到的对应得上。如果发端抓包显示 1-100 全发出去了收端抓包只看到 1-80那就是中间链路丢包如果收端看到 1-100 但 iperf3 仍报丢包那可能是收端网卡缓冲区溢出属于本机问题。5. 避坑清单TCP/UDP 测试里最常翻车的五个点网络调试的坑很多不是协议本身的问题而是工具使用方式和环境配置的问题。下面这五条是我反复踩过的按「现象 → 原因 → 解决」写复制到你的排错手册里直接能用。5.1 现象nc 连接成功但服务端没收到业务数据用 nc 连上了端口客户端这边也显示数据发送完毕服务端日志却什么都没有。原因是 TCP 的 Nagle 算法和发送缓冲导致的粘包或延迟。nc 默认不关闭 Nagle小数据包会在本地缓冲要等 ACK 或超时才会批量发出。解决方法是改用 ncat 的-C参数模拟 TCP 连接中常用的「立即发送」语义或者用 socat 设置 TCP_NODELAYsocat - TCP:192.168.1.100:9000,tcp-nodelay另外检查是不是发完数据立刻关闭了连接导致对端来不及处理。在脚本里加一个sleep 0.1再退出很多时候问题就消失了。5.2 现象iperf3 UDP 打流接收带宽远低于发送带宽发送端显示 10Mbps 全部发出接收端只收到 7Mbps丢包率却显示 0%。这是因为停止发送后接收端还会继续从缓冲区读取数据「丢包率」只统计了测试窗口内的数据。真正的瓶颈是接收端没有用-P多线程或者缓冲区太小。解决方法是接收端加大 Socket 缓冲区iperf3 -s -w 4M-w参数在 UDP 模式下也能设置 Socket 接收缓冲区。另外检查网卡的 coalesce 和 interrupt 参数尤其在高吞吐场景下软中断处理不过来会导致收包做丢弃。5.3 现象TCP 端口被防火墙悄悄 droptcpdump 抓包能看到 SYN 发出去了但是没有 SYN-ACK 回来本机和目标机器防火墙都放行了对应端口。这种情况多半是防火墙 zone 或 cloud security group 的默认策略问题。我遇到过一次iptables 的 INPUT 链放行了 9000 端口但 FORWARD 链没放行数据包走进来直接被丢。检查顺序是先看本机iptables -L再看中间路由和云安全组最后看目标机器的ss -lnt确认监听在 0.0.0.0 而不是 127.0.0.1。5.4 现象Windows 上开启 TCP timestamps 后连接频频 RST这个我经历过一次典型的翻车。某台 Windows 机器执行过netsh int tcp set global timestampsenabled之后陆续出现和 Linux 服务端连接建立成功但传输大文件时被 RST 的情况。原因在 NAT 环境下TCP 时间戳的 PAWS保护旧报文机制误判了正常报文。解决方法是查看当前状态必要时恢复默认netsh int tcp show global netsh int tcp set global timestampsdisabled注意改动会影响全局 TCP 行为生产环境机谨慎操作最好先在测试环境复现确认。5.5 现象Docker/NAT 端口映射环境下 TCP 测试结果不一致宿主机上直接测试 TCP 9000 端口没问题但通过 Docker 端口映射测试却不稳定。根源是 Docker 的 NAT 规则和 conntrack 表状态冲突持续高并发下 conntrack 表溢出会随机丢连接。排查手段是看dmesg里有没有 conntrack table full 日志或者执行sysctl net.netfilter.nf_conntrack_max查看上限。临时解决是把映射模式从 bridge 改成 host或者调大 conntrack 上限但最干净的方案是直接测容器 IP不做端口映射排除一层变量。6. 把测试沉淀成脚本留一条可复现的验证路径工具用熟了之后我的习惯是把每一次联调都沉淀成脚本因为手工验证最大的敌人是时间——三个月后同一个服务升级你不可能还记得当初是敲了哪条命令。脚本的核心诉求是一条命令跑完结果可控能进 CI。6.1 一个最小 TCP/UDP 回归脚本#!/bin/bash # 简洁 TCP/UDP 回归测试 TARGET${1:-192.168.1.100} TCP_PORT9000 UDP_PORT9001 # TCP 连通性测试 if ncat -z -w 3 $TARGET $TCP_PORT; then echo TCP_OK $TARGET:$TCP_PORT else echo TCP_FAIL $TARGET:$TCP_PORT fi # UDP 单包收发测试 unset UDP_RESPONSE UDP_RESPONSE$(echo ping | ncat -u -w 2 $TARGET $UDP_PORT 2/dev/null) if [ $UDP_RESPONSE pong ]; then echo UDP_OK $TARGET:$UDP_PORT else echo UDP_FAIL $TARGET:$UDP_PORT fi这里的逻辑包含了两层TCP 测试用-z只探测端口不传数据-w 3控制超时UDP 测试要求对端回pong才认为链路真的可用。UDP 没有握手单纯发一个包出去并不能证明对端收到必须依赖应用层回包。6.2 断言与退出码让结果可以被 CI 消费上面的脚本只是输出CI 需要的是退出码。在脚本末尾加上exit状态判断FAIL_COUNT$(grep -c _FAIL $OUTPUT) if [ $FAIL_COUNT -gt 0 ]; then echo REGRESSION_FAILED exit 1 fi echo REGRESSION_PASSED exit 0这样 GitLab CI 或 Jenkins 就能通过退出码直接判断是绿是红。如果你用 Python 写更推荐用pytest封装测试用例每个用例断言结果失败时打印抓包或日志片段二次排查时有据可查。6.3 我的执行习惯测试脚本里不要写死 IP 和端口参数全走环境变量或命令行传入这样同一套脚本可以跑开发、测试、生产三个环境。关键路径上留set -x开关排查时打开能看到每一步执行了什么命令。所有脚本统一存到 Git 仓库和代码一起版本管理服务端协议一变更先跑脚本再改代码省掉大量无意义的联调时间。这是我的血泪经验也是我想在这里告诉你的最后一条建议——网络测试这件事手工验证能做但可复现的自动验证才能救你于水火。希望帮到你。本文还有配套的精品资源点击获取