Network speed test
网络测速
测量你的设备到东京一台服务器(AWS 东京区域)之间的延迟、抖动、下载与上传速度,以及下载、上传进行时延迟上涨多少。延迟涨得越多,网络忙的时候视频通话和游戏越容易卡。
测速要和服务器之间收发较多数据(网速 100 Mbit/s 时一次约 250 MB),所以需要先登录 fengzee.me 账户。结果会保存在账户里,换一台设备也能看到。
How it works
测速方法
延迟:连续发 22 个很小的请求,去掉前两个(第一个要建立连接),取其余 20 个往返时间的中位数;抖动是相邻两次往返时间之差的平均值。下载与上传:各持续 10 秒,同时发 4 个请求,浏览器通常把它们放在同一条 HTTP/2 或 HTTP/3 连接里;前 2 秒是速度爬升期,不计入,读数是之后约 8 秒的平均速度。网络忙时的延迟:下载与上传进行时每 0.2 秒测一次往返时间,取中位数。
读数反映的是你的设备到东京这一段路径。服务器使用 BBR 拥塞控制,零星的丢包不会让它降速。你离东京越远,往返时间越长,测出的速度可能低于本地运营商提供的测速。
API
测量接口
网页测速用到的接口都可以直接调用。不需要登录的接口每次只交换几百字节,不记录调用者;下载与上传会产生较多流量,需要登录,每次调用都有审计记录,不设用量上限。
回 204,没有正文,不需要登录。测往返时间时取「发出请求到收到响应头」这一段;第一次请求包含建立连接,应当去掉。
curl -so /dev/null -w 'connect %{time_connect} first byte %{time_starttransfer}\n' https://net.fengzee.me/api/v1/ping返回服务器看到的你的公网 IP(forwardedFor)、服务器时间(UTC)与 UDP 回声当前的端口,不需要登录。client 是服务器内部转发时的地址,可以忽略。公网 IP 与设备自己的地址不同,说明中间有 NAT(地址转换)。
curl -s https://net.fengzee.me/api/v1/vantage
{"client":{"ip":"127.0.0.1","port":"55476"},"forwardedFor":"203.0.113.7",
"serverTime":"2026-10-04T11:49:01.217982317Z","udp":{"port":58473}}UDP 端口不经过代理,服务器能看到每个数据报是否到达、到达时的 TTL 与源端口,因此能分清丢包发生在去程还是回程。端口在 58472 与 58473 之间切换,用之前先从 vantage 的 udp.port 取。数据报以 20 字节的头开始,字段按网络字节序排列,见下表。类型 0x01 是回声请求,服务器以同样长度回 0x02,写入收到与发出的时刻(微秒)、观测到的 TTL 与源端口;0x03 请求统计,服务器回 0x04,用位图说明这个会话的哪些序号到了,并附上首末包的到达间隔;0x05 请求下行包,服务器按要求发出 0x06。
offset bytes field
0 4 magic "NETQ"
4 1 version = 1
5 1 kind: 0x01 echo 0x02 echo reply 0x03 report 0x04 report reply
0x05 downlink request 0x06 downlink data
6 2 flags (bit 0: count only, no echo)
8 8 session
16 4 seq (0-1023)这个端口不需要登录。为了不被伪造源地址的请求用作反射放大器,服务器发出的下行字节不超过同一会话已送达上行字节的 3 倍,每轮至多 1024 个序号,会话 2 分钟后过期。
X-Net-Client: web:这个请求头让别的网站无法借用你的登录状态发起下载或上传。程序调用用 OAuth 2.0 访问令牌(Authorization: Bearer),令牌目前只签发给站点自己的客户端。返回 N 个随机字节,N 取 1 到 1,000,000,000,不写时为 10,000,000。内容无法压缩,Content-Length 写明总长。从收到响应头开始计时,按实际收到的字节算速度;可以要一个很大的 N,到时间后主动断开。
curl -o /dev/null -H "Authorization: Bearer $TOKEN" \
-w '%{http_code} %{speed_download} bytes/s\n' \
'https://net.fengzee.me/api/v1/bulk/down?bytes=25000000'收下请求体并丢弃,回一个 JSON:bytes 是收到的字节数,micros 是第一个字节到最后一个字节之间的微秒数。请求体可以带 Content-Length,也可以分块传输,至多 1 GB。上传速度以收到这个回应的时刻为准计时,micros 供对照。
head -c 25000000 /dev/urandom | curl -sS -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/octet-stream' --data-binary @- \
https://net.fengzee.me/api/v1/bulk/up
{"bytes": 25000000, "micros": 4183925}POST 保存一次测速的读数(下面是请求体的样子,测不到的项写 null),服务器补上时间、公网 IP 与浏览器标识。requestId 由调用方为每次测速生成(16 到 64 位字母、数字、下划线或短横线),同一次结果重发不会重复保存。GET 返回你自己最近 20 次的结果。两者都需要登录。
{"requestId": "3f0c2a8e-5b1d-4e7a-9c64-1d2e3f4a5b6c", "streams": 4, "protocol": "h2",
"downMbps": 48.2, "upMbps": 21.5,
"idleMs": 24.1, "jitterMs": 1.8, "loadedDownMs": 61.0, "loadedUpMs": 140.3,
"downBytes": 60250000, "upBytes": 26870000}/api/v1/wifi/),需要单独授权,本页不介绍。