ping 不通但网站能打开?tcping 与 ICMP ping 的区别和正确用法

Blog / 网络基础

ping 不通但网站能打开?tcping 与 ICMP ping 的区别和正确用法

ping 不通但网站能打开,最常见的原因是对方或中间网络过滤了 ICMP,而网页走的是 TCP 443,两者互不相干。想知道某个服务“到底通不通、有多远”,应该用 tcping 这类工具直接对业务端口发起 TCP 握手,或者用 curl -w 把 DNS、TCP、TLS 各段时间拆开看。tcping 比 ping 更接近真实访问,但也有两个容易读错的地方:RST 和本机代理。

ping 不通为什么网站还能打开?

ping 发的是 ICMP Echo Request,等对方回一个 Echo Reply。它不经过任何端口,也不经过 Web 服务器,回应它的是对方操作系统的网络栈,或者更早的某个设备。

ICMP 在下面几种情况下会“失真”:

  • 被直接过滤:不少云服务器的安全组默认不放行入站 ICMP,部分 API 入口和 CDN 节点也不回应 ping。这时 ping 100% 超时,但 443 端口完全正常。
  • 被限速或降低优先级:路由器对发给自己的 ICMP、以及 TTL 超时报文的生成,通常交给控制面处理并限速;有的网络还会对经过的 ICMP 整体限速。于是 ping 显示的延迟偏高、偶尔丢包,而同一路径上的 TCP 流量并没有受影响。这也是 traceroute 中间跳出现星号或延迟突增的常见原因,读法见 traceroute 和 mtr 结果怎么看.
  • 走了不同的路径:有的网络对 ICMP 和 TCP 做不同的策略路由,代理软件一般也只接管 TCP(和部分 UDP),ICMP 仍然从本地出口直接发出。开着代理 ping 一个海外域名,测到的是“本地直连”的路径,而浏览器访问走的是代理,两者没有可比性。

所以 ping 的结论只能是“ICMP 这条路的情况”。它通了,不代表 443 能用;它不通,也不代表服务挂了。

tcping 测的到底是什么?

tcping 对指定的 IP 和端口发起一次 TCP 连接:发出 SYN,等对方回 SYN-ACK,记下这个往返用了多久,然后关闭连接。它测的是 TCP 三次握手的第一个往返,不发 HTTP 请求,也不做 TLS 握手。

和 ping 相比,它有两点更贴近真实访问:

  1. 用的是业务协议和业务端口,能被 ICMP 过滤规则影响的情况少了一大类。
  2. 能顺便回答“端口开没开”:收到 SYN-ACK 说明有程序在监听。

RST 也算“有响应”:最容易看错的地方

TCP 握手有三种结果:

对方回应含义常见工具的表现
SYN-ACK端口开放,有服务在监听显示 open / 连接成功,给出耗时
RST主机可达,但端口没有服务,或被防火墙主动拒绝部分工具显示 closed,也有工具照样给出一个耗时
无回应被防火墙静默丢弃,或路由不通超时(timeout / filtered)

问题出在第二行。RST 也是一个完整的往返,有些工具(尤其是发原始 SYN 包的工具,比如 hping3)会把它的耗时照常打印出来,只在标志位里写着 RA。只看数字的话,会误以为“端口通,延迟 40 ms”。读 tcping 结果时,先确认状态是 open,再看耗时。

本机代理会“替”对方完成握手

开启 TUN 模式或透明代理时,很多代理客户端会在本机直接接受 TCP 连接,再转发出去。此时 tcping 任何海外地址都可能显示 1 ms 左右、端口全开,测到的只是你和本机代理之间的握手。CDN 也有类似情况:TCP 在离你最近的边缘节点就终止了,tcping 测到的是你到边缘的距离,不是到源站。

判断方法很简单:同一个目标,关掉代理测一次、开着代理测一次;或者 tcping 一个肯定不存在服务的地址和端口,如果也“秒通”,说明握手被本地接管了。

三种测量方式放在一起对比

ICMP pingtcping(TCP 握手)HTTPS 首次连接(curl / 浏览器)
协议与端口ICMP,无端口TCP,指定端口TCP 443 + TLS + HTTP
测到的时间1 个 ICMP 往返1 个 TCP 往返DNS + TCP 握手 + TLS 握手(+ 首字节)
能发现端口不通不能能能
能发现证书、SNI、TLS 层问题不能不能能
是否经过代理通常不经过取决于代理模式和真实应用一致
适合回答的问题主机在网络层是否可达(前提是不过滤 ICMP)业务端口开没开、TCP 往返多少真实请求在连接阶段要花多久、卡在哪一段

越往右越接近应用实际遇到的情况,代价是测量更重、受更多因素影响。排查时建议从右往左用:先用 curl 看哪一段慢,再用 tcping 确认 TCP 层,最后才看 ping 和 traceroute。

各系统怎么测端口和握手延迟?

下面以 api.openai.com:443 为例。示例输出只用来说明格式,数字不是实测值。

Windows:tcping.exe 与 PowerShell

Windows 没有自带 tcping,常见的是一个单文件的 tcping.exe,下载后放进任意在 PATH 里的目录即可。请从项目的原始发布页下载,下载后核对数字签名或哈希。

tcping -n 5 api.openai.com 443

输出大致是每行一次探测,带 Port is open 和 time=xx.xxxms,最后给出最小、最大、平均值。如果显示 No response,就是超时。

不想装软件的话,PowerShell 自带的命令可以判断端口是否开放:

Test-NetConnection api.openai.com -Port 443

看 TcpTestSucceeded : True 即可。它不适合用来测延迟,结果里的 PingReplyDetails 是 ICMP 的数据,不是 TCP 握手时间。

macOS 与 Linux:nc 和 nping

nc(netcat)系统一般自带:

nc -vz -w 3 api.openai.com 443

succeeded / open 表示握手成功,Connection refused 对应 RST,超时说明没有回应。nc 不打印耗时,需要的话套一层 time:

time nc -z -w 3 api.openai.com 443

这样测到的时间包含 DNS 解析,想排除 DNS 就直接写 IP。

需要连续测、看抖动时,可以用 nmap 附带的 nping,它的 --tcp-connect 模式走系统的正常 connect,不需要 root:

nping --tcp-connect -p 443 -c 10 api.openai.com

最后一行会给出 Max rtt / Min rtt / Avg rtt。Linux 发行版仓库里也有叫 tcping 的包,不同发行版的实现不一样,参数以 tcping -h 为准。

通用:curl -w 拆分每一段时间

这是测 API 最推荐的一条命令,三个系统都能用(Windows 10 1803 及之后的版本自带 curl,PowerShell 里要写 curl.exe,并把 -o /dev/null 换成 -o NUL):

curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nTCP: %{time_connect}s\nTLS: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总计: %{time_total}s\n" https://api.openai.com/v1/models

这几个值都是从开始计时的累计时间,要相减才是每一段:

  • time_connect - time_namelookup:TCP 握手,和 tcping 测的是同一个东西。
  • time_appconnect - time_connect:TLS 握手。
  • time_starttransfer - time_appconnect:请求发出到收到第一个字节,包含服务端处理。不带密钥访问 /v1/models 通常直接返回 401,这一段基本就是“网络往返 + 网关处理”,不涉及模型推理。

如果 curl 走了代理(设置了 https_proxy 等环境变量),time_connect 测到的是连代理的时间。想区分,就用 --noproxy '*' 再跑一次对比。连接阶段之后的延迟怎么继续拆,见 AI API 延迟拆解:连接建立、网关往返与首 token 时间.

为什么测 AI API 应该测 443,而不是 ping 域名?

多数 AI API 的入口在 CDN 或云负载均衡后面,对 ping 的处理各不相同:有的回应,有的不回应,有的由边缘节点代答。ping 一个 API 域名得到的结果,既不能说明 443 可用,也不能拿来横向比较各家快慢。

实际调用要经过的是:DNS 解析 → TCP 443 握手 → TLS 握手 → HTTP 请求。任何一段出问题,ping 都看不出来。比较典型的几种:

  • DNS 解析到了错误的地址:ping 可能通(只是 ping 错了对象),请求却失败。是否被污染或劫持,可以按 DNS 污染和 DNS 劫持的三步判断来查。
  • TCP 443 被重置或丢弃:ping 正常,tcping 显示 closed 或超时。
  • TLS 握手失败或特别慢:ping 和 tcping 都正常,只有 curl 的 TLS 段异常或报错。

所以排查 Claude Code、Codex 这类工具连不上时,应该按层次逐一检查,而不是 ping 一下就下结论。完整的分层清单见 Claude Code 连接超时和报错怎么排查.

一份可以照做的检查顺序

  1. 运行上面的 curl -w 命令,看在哪一段出错或变慢。
  2. DNS 段慢或报解析错误:换一个解析器对比 dig / nslookup 结果。
  3. TCP 段超时:用 tcping 或 nc -vz 测 443,开关代理各测一次,确认是不是被本机代理接管。
  4. TLS 段报错:检查系统时间、代理证书、是否有中间设备在做 HTTPS 解密。
  5. 连接都正常但请求失败:看 HTTP 状态码,再去 API 状态页 确认上游有没有事件。
  6. 最后才用 ping 和 mtr 看路径,判断是不是中间某段网络有问题。

日常需要定期做的项目,可以对照 开发者网络自检清单(2026 版).

cdnping 首页的“首次连接”和“往返”分别对应什么?

cdnping 的Online speed test在浏览器里测 15 个 AI 模型 API 和 9 个公共前端 CDN,给出两个数字,和前面三种测量可以这样对上:

cdnping 指标包含什么对应的命令行测量
First connectionDNS 解析 + TCP 握手 + TLS 握手,以及第一次请求大致相当于 curl 的 time_starttransfer
Round trip连接复用后再发 3 次请求,取中位数去掉建连开销后的单次请求往返,接近 tcping 的 TCP 往返加上服务端入口处理时间

两个数字差得多,说明大部分时间花在建连上:DNS 慢、RTT 大导致 TCP 和 TLS 握手被放大,或者 TLS 握手本身有问题。这种情况下,客户端开启连接复用(keep-alive、HTTP/2)收益最大。两个数字都高,说明你和入口之间的往返本身就远,复用连接也省不掉。

浏览器测速走的是浏览器的网络栈,开着代理就会经过代理,所以它反映的是“你的浏览器实际访问这些 API 的情况”,这一点和 tcping 在 TUN 模式下只测到本机不同。测量细节见 Methodology。如果想确认自己的出口 IP、是否走了代理、浏览器往返和出口 TCP 往返是否对得上,可以用 IP & environment check,其中延迟特征一项正是拿浏览器往返和 Cloudflare 测得的出口 TCP 往返做对比,原理见 网站如何用延迟判断你在用代理.

一份边缘探测数据怎么读

cdnping 的 API 状态页 从 Cloudflare 边缘每 5 分钟探测一次各官方 API 入口。下面取自 2026-10-17 的首批快照:探测节点是 DEN(美国丹佛),窗口为 UTC 08:40–10:05,所有入口合计 242 次探测。cdnping 从这一天才开始采集,数据只覆盖这一个多小时,不是长期统计。数据以 CC BY 4.0 发布。

入口中位数(ms)P95(ms)
api.anthropic.com7384
api.openai.com96194
api.deepseek.com353414
dashscope.aliyuncs.com6151152

这些数字主要反映丹佛到各入口的网络距离,海外入口和国内入口的差距来自地理位置,不说明哪家服务更快。中位数和 P95 的差距可以多看一眼:同样的探测,有的入口 P95 接近中位数,有的接近两倍,后者意味着偶发的慢请求更多。你在自己的网络里用 tcping 或 curl 测,排序和数值都可能完全不同,结论要以本地实测为准。

Related articles

Keep reading