---
title: "ping 不通但网站能打开？tcping 与 ICMP ping 的区别和正确用法"
description: "ping 超时网站却能打开，是因为网络对 ICMP 和 TCP 的处理不同。本文讲清 ping、tcping、HTTPS 首次连接分别测什么，给出 Windows、macOS、Linux 的端口测试命令和读数陷阱。"
url: https://cdnping.org/blog/ping-vs-tcping-port-latency
language: zh-CN
published: 2026-10-25
category: "网络基础"
tags: ["tcping","ping","端口测试","网络延迟","curl","网络排查"]
source: cdnping.org
license: Free to quote and summarize with a link to the url above.
---
# 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 结果怎么看](/blog/traceroute-mtr-how-to-read)。
- 走了不同的路径：有的网络对 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 ping | tcping（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 里的目录即可。请从项目的原始发布页下载，下载后核对数字签名或哈希。

```powershell
tcping -n 5 api.openai.com 443
```

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

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

```powershell
Test-NetConnection api.openai.com -Port 443
```

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

### macOS 与 Linux：nc 和 nping

`nc`（netcat）系统一般自带：

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

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

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

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

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

```bash
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`）：

```bash
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 时间](/blog/api-latency-connect-rtt-ttft)。

## 为什么测 AI API 应该测 443，而不是 ping 域名？

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

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

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

所以排查 Claude Code、Codex 这类工具连不上时，应该按层次逐一检查，而不是 ping 一下就下结论。完整的分层清单见 [Claude Code 连接超时和报错怎么排查](/blog/claude-code-connection-troubleshooting)。

### 一份可以照做的检查顺序

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

日常需要定期做的项目，可以对照 [开发者网络自检清单（2026 版）](/blog/developer-network-self-check-2026)。

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

cdnping 的[在线测速](/)在浏览器里测 15 个 AI 模型 API 和 9 个公共前端 CDN，给出两个数字，和前面三种测量可以这样对上：

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

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

浏览器测速走的是浏览器的网络栈，开着代理就会经过代理，所以它反映的是“你的浏览器实际访问这些 API 的情况”，这一点和 tcping 在 TUN 模式下只测到本机不同。测量细节见 [数据方法](/methodology)。如果想确认自己的出口 IP、是否走了代理、浏览器往返和出口 TCP 往返是否对得上，可以用 [IP 与环境检测](/ip)，其中延迟特征一项正是拿浏览器往返和 Cloudflare 测得的出口 TCP 往返做对比，原理见 [网站如何用延迟判断你在用代理](/blog/how-sites-detect-proxy-by-latency)。

### 一份边缘探测数据怎么读

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

| 入口 | 中位数（ms） | P95（ms） |
| --- | --- | --- |
| api.anthropic.com | 73 | 84 |
| api.openai.com | 96 | 194 |
| api.deepseek.com | 353 | 414 |
| dashscope.aliyuncs.com | 615 | 1152 |

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