fengzee.me / Speed test

Network speed test

网络测速

测量你的设备到东京一台服务器(AWS 东京区域)之间的延迟、抖动、下载与上传速度,以及下载、上传进行时延迟上涨多少。延迟涨得越多,网络忙的时候视频通话和游戏越容易卡。

登录后测速

测速要和服务器之间收发较多数据(网速 100 Mbit/s 时一次约 250 MB),所以需要先登录 fengzee.me 账户。结果会保存在账户里,换一台设备也能看到。

测速方法

延迟:连续发 22 个很小的请求,去掉前两个(第一个要建立连接),取其余 20 个往返时间的中位数;抖动是相邻两次往返时间之差的平均值。下载与上传:各持续 10 秒,同时发 4 个请求,浏览器通常把它们放在同一条 HTTP/2 或 HTTP/3 连接里;前 2 秒是速度爬升期,不计入,读数是之后约 8 秒的平均速度。网络忙时的延迟:下载与上传进行时每 0.2 秒测一次往返时间,取中位数。

读数反映的是你的设备到东京这一段路径。服务器使用 BBR 拥塞控制,零星的丢包不会让它降速。你离东京越远,往返时间越长,测出的速度可能低于本地运营商提供的测速。

记录了什么每次测速在你的账户下保存读数、时间、公网 IP 与浏览器标识;下载与上传的每个请求另有一条审计记录:账户、来源 IP、方向、请求与实际传输的字节数、耗时。站点管理员能看到这些记录。

测量接口

网页测速用到的接口都可以直接调用。不需要登录的接口每次只交换几百字节,不记录调用者;下载与上传会产生较多流量,需要登录,每次调用都有审计记录,不设用量上限。

GET/api/v1/ping往返时间

回 204,没有正文,不需要登录。测往返时间时取「发出请求到收到响应头」这一段;第一次请求包含建立连接,应当去掉。

curl -so /dev/null -w 'connect %{time_connect}  first byte %{time_starttransfer}\n' https://net.fengzee.me/api/v1/ping
GET/api/v1/vantage你的公网地址

返回服务器看到的你的公网 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}}
UDPnet.fengzee.me:58472 | 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,或 Bearer 访问令牌
用量上限无
单次上限1 GB
超时30 秒没有进展即断开
怎样登录在本页登录 fengzee.me 账户后,同一网页里的请求会自动带上登录状态(Cookie),另外必须带请求头 X-Net-Client: web:这个请求头让别的网站无法借用你的登录状态发起下载或上传。程序调用用 OAuth 2.0 访问令牌(Authorization: Bearer),令牌目前只签发给站点自己的客户端。
GET/api/v1/bulk/down?bytes=N下载

返回 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'
POST/api/v1/bulk/up上传

收下请求体并丢弃,回一个 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}
GET · POST/api/v1/speedtests测速结果

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}
审计记录下载与上传在开始传输前先写一条记录,写不进去就不传,回 503;传完后补上实际传输的字节数、耗时与结局(完成、中断或超过上限)。网页测速按时长结束,下载请求的结局通常是「中断」,字节数是实际传出的部分。
错误401:没有登录或令牌无效。400:参数不在范围内。413:超过 1 GB。422:测速结果的读数超出范围。503:审计记录或数据库暂时不可用。
另有供站点自有客户端同步测量记录的接口(/api/v1/wifi/),需要单独授权,本页不介绍。