mirror of
https://github.com/XIU2/CloudflareSpeedTest.git
synced 2026-03-08 07:35:52 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2de42f8d30 | ||
|
|
bcbf7f0e2a | ||
|
|
f735c0f5b3 | ||
|
|
7fbe1d1b56 | ||
|
|
6eaacd6b2c | ||
|
|
b955387787 | ||
|
|
e57e9d3897 | ||
|
|
801dd53774 | ||
|
|
e03a371e19 | ||
|
|
346b27f011 | ||
|
|
4f9ca03008 | ||
|
|
d76a8bc749 | ||
|
|
3cd9a35994 | ||
|
|
574e419ee1 | ||
|
|
d66b2aa1f0 |
103
README.md
103
README.md
@@ -25,7 +25,7 @@
|
||||
|
||||
### 下载运行
|
||||
|
||||
1. 下载编译好的可执行文件( [Github Releases](https://github.com/XIU2/CloudflareSpeedTest/releases) / [蓝奏云](https://pan.lanpw.com/b0742hkxe) )并解压。
|
||||
1. 下载编译好的可执行文件( [Github Releases](https://github.com/XIU2/CloudflareSpeedTest/releases) / [蓝奏云](https://xiu.lanzoub.com/b0742hkxe) )并解压。
|
||||
2. 双击运行 `cfst.exe` 文件(Windows 系统),等待测速完成...
|
||||
|
||||
<details>
|
||||
@@ -33,7 +33,8 @@
|
||||
|
||||
****
|
||||
|
||||
通过scoop安装:
|
||||
如果你有 scoop(Windows 下的命令行安装程序),则可以这样安装:
|
||||
|
||||
```sh
|
||||
# 添加最多人使用的中文软件包仓库:dorado
|
||||
scoop bucket add dorado https://github.com/chawyehsu/dorado
|
||||
@@ -58,13 +59,13 @@ mkdir cfst
|
||||
cd cfst
|
||||
|
||||
# 下载 CFST 压缩包(自行根据需求替换 URL 中 [版本号] 和 [文件名])
|
||||
wget -N https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_amd64.tar.gz
|
||||
wget -N https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.4/cfst_linux_amd64.tar.gz
|
||||
# 如果你是在国内网络环境中下载,那么请使用下面这几个镜像加速之一:
|
||||
# wget -N https://ghfast.top/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
|
||||
# wget -N https://wget.la/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
|
||||
# wget -N https://ghproxy.net/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
|
||||
# wget -N https://gh-proxy.com/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
|
||||
# wget -N https://hk.gh-proxy.com/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
|
||||
# wget -N https://wget.la/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.4/cfst_linux_amd64.tar.gz
|
||||
# wget -N https://ghfast.top/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.4/cfst_linux_amd64.tar.gz
|
||||
# wget -N https://ghproxy.it/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.4/cfst_linux_amd64.tar.gz
|
||||
# wget -N https://gh-proxy.org/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.4/cfst_linux_amd64.tar.gz
|
||||
# wget -N https://cdn.gh-proxy.org/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.4/cfst_linux_amd64.tar.gz
|
||||
# 如果下载失败的话,尝试删除 -N 参数(如果是为了更新,则记得提前删除旧压缩包 rm cfst_linux_amd64.tar.gz )
|
||||
|
||||
# 解压(不需要删除旧文件,会直接覆盖,自行根据需求替换 文件名)
|
||||
@@ -77,7 +78,7 @@ chmod +x cfst
|
||||
./cfst
|
||||
|
||||
# 运行(带参数示例)
|
||||
./cfst -dd -tll 90
|
||||
./cfst -tl 200 -dn 20
|
||||
```
|
||||
|
||||
> 如果平**均延迟非常低**(如 0.xx),则说明 CFST **测速时走了代理**,请先关闭代理软件后再测速。
|
||||
@@ -201,6 +202,7 @@ https://github.com/XIU2/CloudflareSpeedTest
|
||||
指定IP段数据;直接通过参数指定要测速的 IP 段数据,英文逗号分隔;(默认 空)
|
||||
-o result.csv
|
||||
写入结果文件;如路径含有空格请加上引号;值为空时不写入文件 [-o ""];(默认 result.csv)
|
||||
注意:在一些环境下使用 -o "" 可能会被忽略掉这个空参数导致报错,可加个空格 -o " " 解决
|
||||
|
||||
-dd
|
||||
禁用下载测速;禁用后测速结果会按延迟排序 (默认按下载速度排序);(默认 启用)
|
||||
@@ -283,7 +285,9 @@ CFST 会先延迟测速,在这过程中进度条右侧会实时显示可用 IP
|
||||
|
||||
****
|
||||
|
||||
另外,如果全部队列 IP 都测速完了,但一个满足下载速度条件的 IP 都没有,你可能需要调低预期的下载测速下限条件,但你需要知道当前的大概测速速度都在什么范围,那么你就可以加上 `-debug` 参数开启调试模式,这样再遇到这种情况时,就会**忽略条件返回所有测速数据**,你就能看到这些 IP 的下载速度都有多少,心里也就有数了,然后**适当调低 `-sl` 再试试**。
|
||||
另外,如果全部队列 IP 都测速完了,但一个满足下载速度条件的 IP 都没有,你可能需要调低预期的下载测速下限条件,但你需要知道当前的大概测速速度都在什么范围,那么你就可以加上 `-debug` 参数开启调试模式,这样再遇到这种情况时,就会**忽略条件返回所有测速结果**,你就能看到这些 IP 的下载速度都有多少,心里也就有数了,然后**适当调低 `-sl` 再试试**。
|
||||
|
||||
> 注意,如果你**没有指定**下载测速下限 `-sl` 条件,那么无论什么情况下 CFST 都会**输出所有测速结果**。
|
||||
|
||||
同样,延迟测速方面,`可用: 30`、`队列:10` 这两个数值也可以让你清楚,你设置的延迟条件对你来说是否过于苛刻。如果可用 IP 一大堆,但条件过滤后只剩下 2、3 个,那不用说就知道需要**调低预期的延迟/丢包条件**了。
|
||||
|
||||
@@ -298,9 +302,9 @@ CFST 会先延迟测速,在这过程中进度条右侧会实时显示可用 IP
|
||||
Windows 要指定参数需要在 CMD 中运行,或者把参数添加到快捷方式目标中。
|
||||
|
||||
> [!TIP]
|
||||
> - 各参数均有**默认值**,使用默认值的参数是可以省略的(**按需选择**),参数**不分前后顺序**。
|
||||
> - 各参数均有**默认值**,当使用默认值时参数可以省略(**按需选择**),参数**不分前后顺序**。
|
||||
> - Windows **PowerShell** 只需把下面命令中的 `cfst.exe` 改为 `.\cfst.exe` 即可。
|
||||
> - Linux 系统只需要把下面命令中的 `cfst.exe` 改为 `./cfst` 即可。
|
||||
> - Linux / macOS 系统只需要把下面命令中的 `cfst.exe` 改为 `./cfst` 即可。
|
||||
|
||||
****
|
||||
|
||||
@@ -313,22 +317,23 @@ Windows 要指定参数需要在 CMD 中运行,或者把参数添加到快捷
|
||||
|
||||
****
|
||||
|
||||
很多人打开 CMD 以**绝对路径**运行 CFST 会报错,这是因为默认的 `-f ip.txt` 参数是相对路径,需要指定绝对路径的 ip.txt 才行,但这样毕竟太麻烦了,因此还是建议进入 CFST 程序目录下,以**相对路径**方式运行:
|
||||
很多人打开 CMD 直接就以**绝对路径**运行 CFST 会报错,这是因为默认的 `-f ip.txt` 参数是相对路径,需要指定绝对路径的 ip.txt 才行,但这样毕竟太麻烦了,因此还是建议进入 CFST 程序目录下,以**相对路径**方式运行:
|
||||
|
||||
**方式 一**:
|
||||
1. 打开 CFST 程序所在目录
|
||||
2. 空白处按下 <kbd>Shift + 鼠标右键</kbd> 显示右键菜单
|
||||
3. 选择 **\[在此处打开命令窗口\]** 来打开 CMD 窗口,此时默认就位于当前目录下
|
||||
4. 输入带参数的命令,如:`cfst.exe -tll 50 -tl 200`即可运行
|
||||
4. 输入带参数的命令,如:`cfst.exe -tl 200 -dn 20` 即可运行
|
||||
|
||||
**方式 二**:
|
||||
1. 打开 CFST 程序所在目录
|
||||
2. 直接在文件夹地址栏中全选并输入 `cmd` 回车来打开 CMD 窗口,此时默认就位于当前目录下
|
||||
4. 输入带参数的命令,如:`cfst.exe -tll 50 -tl 200`即可运行
|
||||
2. 直接在文件夹地址栏中全选(或清空)并输入 `cmd` 回车就能打开 CMD 窗口,此时默认就位于当前目录下
|
||||
4. 输入带参数的命令,如:`cfst.exe -tl 200 -dn 20` 即可运行
|
||||
|
||||
> 当然你也可以随便打开一个 CMD 窗口,然后输入如 `cd /d "D:\Program Files\cfst"` 来进入程序目录
|
||||
|
||||
> **提示**:如果用的是 **PowerShell** 只需把命令中的 `cfst.exe` 改为 `.\cfst.exe` 即可。
|
||||
> **提示**:如果用的是 **PowerShell** 只需把命令中的 `cfst.exe` 改为 `.\cfst.exe` 即可。
|
||||
> **注意**:在 **PowerShell** 下使用 `-o ""` 会被忽略掉空参数导致报错,可加个空格 `-o " "` 解决
|
||||
|
||||
</details>
|
||||
|
||||
@@ -346,11 +351,11 @@ Windows 要指定参数需要在 CMD 中运行,或者把参数添加到快捷
|
||||
右键 `cfst.exe` 文件 - **\[创建快捷方式\]**,然后右键该快捷方式 - **\[属性\]**,修改其**目标**:
|
||||
|
||||
``` bash
|
||||
# 如果要不输出结果文件,那么请加上 -o " ",引号里的是空格(没有空格会导致该参数被省略)。
|
||||
D:\ABC\cfst\cfst.exe -n 500 -t 4 -dn 20 -dt 5 -o " "
|
||||
# 如果要不输出结果文件,那么请加上 -o " ",引号里的是空格(不加空格会导致该空参数被忽略从而报错)。
|
||||
D:\ABC\cfst\cfst.exe -tl 200 -dn 20 -o " "
|
||||
|
||||
# 如果文件路径包含引号,则需要把启动参数放在引号外面,记得引号和 - 之间有空格。
|
||||
"D:\Program Files\cfst\cfst.exe" -n 500 -t 4 -dn 20 -dt 5 -o " "
|
||||
"D:\Program Files\cfst\cfst.exe" -tl 200 -dn 20 -o " "
|
||||
|
||||
# 注意!快捷方式 - 起始位置 不能是空的,否则就会因为绝对路径而找不到 ip.txt 文件
|
||||
```
|
||||
@@ -603,10 +608,11 @@ cfst.exe -tlr 0.25
|
||||
cfst.exe -sl 5 -dn 10
|
||||
```
|
||||
|
||||
> 如果**没有找到一个满足速度**条件的 IP,那么不会输出任何内容,你可能需要调低预期的下载测速下限条件,但你需要知道当前的大概测速速度都在什么范围,那么你就可以加上 `-debug` 参数开启调试模式,这样再遇到这种情况时,就会**忽略条件返回所有测速数据**,你就能看到这些 IP 的下载速度都有多少,心里也就有数了,然后**适当调低 `-sl` 再试试**。
|
||||
> 如果**没有找到一个满足速度**条件的 IP,那么不会输出任何内容,你可能需要调低预期的下载测速下限条件,但你需要知道当前的大概测速速度都在什么范围,那么你就可以加上 `-debug` 参数开启调试模式,这样再遇到这种情况时,就会**忽略条件返回所有测速结果**,你就能看到这些 IP 的下载速度都有多少,心里也就有数了,然后**适当调低 `-sl` 再试试**。
|
||||
> 注意,如果你**没有指定**下载测速下限 `-sl` 条件,那么无论什么情况下 CFST 都会**输出所有测速结果**。
|
||||
|
||||
> 没有指定平均延迟上限时,如果一直**凑不够**满足条件的 IP 数量,就会**一直测速**下去。
|
||||
> 所以建议**同时指定 [下载速度下限] + [平均延迟上限]**,这样测速到指定延迟上限还没凑够数量,就会终止测速。
|
||||
> 建议**同时指定 [下载速度下限] + [平均延迟上限]**,这样测速到指定延迟上限还没凑够数量,就会终止测速。
|
||||
|
||||
****
|
||||
|
||||
@@ -626,6 +632,33 @@ cfst.exe -tl 200 -sl 5.6 -dn 10
|
||||
> 因为 Cloudflare 公开的 IP 段是**回源 IP+任播 IP**,而**回源 IP**是无法使用的,所以下载测速是 0.00。
|
||||
> 运行时可以加上 `-sl 0.01`(下载速度下限),过滤掉**回源 IP**(下载测速低于 0.01MB/s 的结果)。
|
||||
|
||||
****
|
||||
|
||||
为了避免大家迷糊,我列出了在各种条件组合下的预期输出结果都是什么样的。
|
||||
|
||||
**没有指定任何 延迟/速度条件 (即都是默认值):**
|
||||
- 无论如何,都直接输出 **所有测速结果**
|
||||
|
||||
****
|
||||
|
||||
**指定了任何 延迟条件(`-tl` `-tll`,且无论是否开启调试模式 `-debug` 都一样):**
|
||||
- 如果找到最少 1 个满足条件的 IP,则只输出 **这几个满足条件的 IP**(如没有禁用下载测速,则会继续下载测速)
|
||||
- 如果没找到任何满足条件的 IP,则会输出 **空**(如没有禁用下载测速,也会因为数量为 0 而跳过下载测速)
|
||||
|
||||
****
|
||||
|
||||
**指定了任何 下载速度条件 (`-sl`):**
|
||||
|
||||
且当 **关闭 调试模式** 时(即没加上 `-debug` 参数,这种情况下和延迟测速的逻辑完全一致):
|
||||
|
||||
- 如果找到最少 1 个满足条件的 IP,则只输出 **这几个满足条件的 IP**
|
||||
- 如果没找到任何满足条件的 IP,则输出 **空**
|
||||
|
||||
且当 **开启 调试模式** 时(即加上了 `-debug` 参数,延迟测速并没有加上下面第二条里的逻辑,所以依然输出 空):
|
||||
|
||||
- 如果找到最少 1 个满足条件的 IP,则只输出 **这几个满足条件的 IP**
|
||||
- 如果没找到任何满足条件的 IP,则直接输出 **所有测速结果**
|
||||
|
||||
</details>
|
||||
|
||||
****
|
||||
@@ -706,15 +739,19 @@ cfst.exe -f 1.txt
|
||||
常见的下载测速失败报错原因有(因为是 Go 语言的原生报错信息,因此基本都是英文):
|
||||
|
||||
1. `... read: connection reset by peer ... `
|
||||
**链接被重置**,可能是下载测速地址被阻断了,可能是蔷干的,也可能是运营商干的(比如移动或部分地区的白名单)
|
||||
**链接被重置**,可能是下载测速地址被阻断了 或测速 IP 被针对性 HTTPS 阻断了,可能是蔷干的,也可能是运营商干的(比如移动或部分地区的白名单),当然也可能是测速 IP 服务器单纯的重置了你这个不合法的链接请求
|
||||
2. `... HTTP 状态码: 403 ...`
|
||||
像这种直接提示 **HTTP 状态码**的,比较好判断,如 403 就是下载测速地址禁止你访问,404 就是下载测速地址路径对应的文件找不到,具体可以搜索 HTTP 状态码含义
|
||||
像这种直接提示 **HTTP 状态码**的,比较好判断,如 403 就是下载测速地址禁止你访问,404 就是下载测速地址路径对应的文件找不到(具体其他的可以搜索 HTTP 状态码含义)
|
||||
3. `... context deadline exceeded (Client.Timeout exceeded while awaiting headers) ...`
|
||||
这种一般是**请求超时**引起的,可能是 IP 或网络问题,也可能是 -dt 下载测速时间设置的太短了(当然默认的 10 秒肯定算不上短)
|
||||
这种一般是**请求超时**引起的,可能是 IP 或网络问题,也可能是 `-dt` 下载测速时间设置的太短了(当然默认的 10 秒肯定算不上短)
|
||||
4. `... tls: handshake failure ...` 或 `... tls: failed to verify certificate ...`
|
||||
这种 **TLS 握手失败/TLS 证书错误** 代表下载测速地址和测速 IP 服务器不匹配,也就是下载测速地址与测速 IP 其中一方有误(例如下载测速地址是托管在 Fastly CDN 的,但测速 IP 是 Cloudflare CDN 的,或者反过来,总之就是你访问下载测速地址时该测速的 IP 服务器告诉你这个网站域名它不认识并把你拒之门外)
|
||||
5. `... tls: failed to verify certificate: x509: certificate signed by unknown authority.`
|
||||
这种代表**系统证书配置有问题**,导致 TLS 握手时无法验证证书,一般是 Termux 内可能会遇到的,解决方法见:https://github.com/XIU2/CloudflareSpeedTest/discussions/61#discussioncomment-13745059
|
||||
这种 **TLS 握手失败/SSL 证书错误** 代表下载测速地址和测速 IP 服务器不匹配,也就是下载测速地址与测速 IP 其中一方有误(例如下载测速地址是托管在 Fastly CDN 的,但测速 IP 是 Cloudflare CDN 的,或者反过来,总之就是你访问下载测速地址时该测速的 IP 服务器告诉你这个网站域名它不认识并把你拒之门外)
|
||||
5. `... tls: failed to verify certificate: x509: certificate is valid for XXX.XX, not YYY.YY ...`
|
||||
这种是 **SSL 证书里没有包含你下载测速地址的域名**,要么是下载测速地址证书配置有问题,要么就是该测速服务器 IP 上并没有该下载测速地址域名对应的 SSL 证书,也就意味着这个服务器 IP 是不能用于该下载测速地址域名的(比如你用谷歌的服务器 IP 去下载测速百度的域名就会这样,或像上面 4 的原因一样)
|
||||
6. `... tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time ...`
|
||||
这种是 **SSL 证书过期了或者尚未到有效时间**,除了这个原因外,也可能是和上面 4、5 的原因一样(这 4、5、6 三种报错可能会同时出现在同一个服务器 IP 上)
|
||||
7. `... tls: failed to verify certificate: x509: certificate signed by unknown authority.`
|
||||
这种代表**系统证书配置有问题**,导致 TLS 握手时无法验证证书,目前只在 Termux 内遇到过(解决方法见:https://github.com/XIU2/CloudflareSpeedTest/discussions/61 帖子末尾)
|
||||
|
||||
> 如果你遇到了其他报错原因,且翻译后还是不懂,可以发 Issues 或 Discussions 询问,我也会更新到这里。
|
||||
> 但注意,发 Issues 或 Discussions 询问时,请记得带上**调试模式下 CFST 输出的完整内容(或者完整截图)**。
|
||||
@@ -794,6 +831,12 @@ _**CFST OpenWrt 路由器插件版 [#174](https://github.com/XIU2/CloudflareSpee
|
||||
- _https://github.com/immortalwrt-collections/openwrt-cdnspeedtest_
|
||||
_**CFST OpenWrt 原生编译版本 [#64](https://github.com/XIU2/CloudflareSpeedTest/discussions/64)**_
|
||||
|
||||
- _https://github.com/GuangYu-yu/CloudflareST-Rust_
|
||||
_**CFST Rust 版本**_
|
||||
|
||||
- _https://github.com/masgzy/CloudflareST_
|
||||
_**CFST 的分支衍生版本(依然是 Go)**_
|
||||
|
||||
- _https://github.com/hoseinnikkhah/CloudflareSpeedTest-English_
|
||||
_**English language version of CFST (Text language differences only) [#64](https://github.com/XIU2/CloudflareSpeedTest/issues/68)**_
|
||||
|
||||
@@ -805,8 +848,8 @@ _**English language version of CFST (Text language differences only) [#64](https
|
||||
|
||||
- _https://github.com/Spedoske/CloudflareScanner_
|
||||
|
||||
> _因为该项目已经很长时间没更新了,而我又产生了很多功能需求,所以我临时学了下 Go 语言就上手了(菜)..._
|
||||
> _本软件基于该项目制作,但**已添加大量功能及修复 BUG**,并根据大家的使用反馈积极添加、优化功能(闲)..._
|
||||
> _因为该项目已经很长时间没更新了,而我又产生了很多功能需求,所以我临时学了下 Go 语言就上手了 (菜)..._
|
||||
> _本软件基于该项目,但**已彻底重构并添加大量功能/修复BUG**,根据大家的使用反馈积极添加/优化功能 (闲)..._
|
||||
|
||||
****
|
||||
|
||||
|
||||
15
go.mod
15
go.mod
@@ -1,8 +1,17 @@
|
||||
module github.com/XIU2/CloudflareSpeedTest
|
||||
|
||||
go 1.14
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/VividCortex/ewma v1.1.1
|
||||
github.com/cheggaaa/pb/v3 v3.0.4
|
||||
github.com/VividCortex/ewma v1.2.0
|
||||
github.com/cheggaaa/pb/v3 v3.1.7
|
||||
github.com/fatih/color v1.18.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
)
|
||||
|
||||
35
go.sum
35
go.sum
@@ -1,17 +1,18 @@
|
||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/cheggaaa/pb/v3 v3.0.4 h1:QZEPYOj2ix6d5oEg63fbHmpolrnNiwjUsk+h74Yt4bM=
|
||||
github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
|
||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||
github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI=
|
||||
github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
|
||||
15
main.go
15
main.go
@@ -109,7 +109,7 @@ https://github.com/XIU2/CloudflareSpeedTest
|
||||
flag.Parse()
|
||||
|
||||
if task.MinSpeed > 0 && time.Duration(maxDelay)*time.Millisecond == utils.InputMaxDelay {
|
||||
fmt.Println("\033[33m[提示] 在使用 [-sl] 参数时,建议搭配 [-tl] 参数,以避免因凑不够 [-dn] 数量而一直测速...\033[0m")
|
||||
utils.Yellow.Println("[提示] 在使用 [-sl] 参数时,建议搭配 [-tl] 参数,以避免因凑不够 [-dn] 数量而一直测速...")
|
||||
}
|
||||
utils.InputMaxDelay = time.Duration(maxDelay) * time.Millisecond
|
||||
utils.InputMinDelay = time.Duration(minDelay) * time.Millisecond
|
||||
@@ -122,9 +122,9 @@ https://github.com/XIU2/CloudflareSpeedTest
|
||||
fmt.Println("检查版本更新中...")
|
||||
checkUpdate()
|
||||
if versionNew != "" {
|
||||
fmt.Printf("*** 发现新版本 [%s]!请前往 [https://github.com/XIU2/CloudflareSpeedTest] 更新! ***", versionNew)
|
||||
utils.Yellow.Printf("*** 发现新版本 [%s]!请前往 [https://github.com/XIU2/CloudflareSpeedTest] 更新! ***", versionNew)
|
||||
} else {
|
||||
fmt.Println("当前为最新版本 [" + version + "]!")
|
||||
utils.Green.Println("当前为最新版本 [" + version + "]!")
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
@@ -141,15 +141,12 @@ func main() {
|
||||
speedData := task.TestDownloadSpeed(pingData)
|
||||
utils.ExportCsv(speedData) // 输出文件
|
||||
speedData.Print() // 打印结果
|
||||
|
||||
if versionNew != "" {
|
||||
fmt.Printf("\n*** 发现新版本 [%s]!请前往 [https://github.com/XIU2/CloudflareSpeedTest] 更新! ***\n", versionNew)
|
||||
}
|
||||
endPrint()
|
||||
endPrint() // 根据情况选择退出方式(针对 Windows)
|
||||
}
|
||||
|
||||
// 根据情况选择退出方式(针对 Windows)
|
||||
func endPrint() {
|
||||
if utils.NoPrintResult() {
|
||||
if utils.NoPrintResult() { // 如果不需要打印测速结果,则直接退出
|
||||
return
|
||||
}
|
||||
if runtime.GOOS == "windows" { // 如果是 Windows 系统,则需要按下 回车键 或 Ctrl+C 退出(避免通过双击运行时,测速完毕后直接关闭)
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
|
||||
****
|
||||
|
||||
#### 2021年12月17日,版本 v1.0.6
|
||||
#### 2025年12月15日,版本 v1.0.5 (cfst_hosts.bat)
|
||||
- **1. 修复** CFST新版本下获取不到第一行 IP 的问题
|
||||
|
||||
#### 2021年12月17日,版本 v1.0.4
|
||||
- **1. 优化** [找不到满足条件的 IP 就一直循环测速] 功能,在指定下载测速下限时没有重新测速的问题(默认注释)
|
||||
|
||||
#### 2021年12月17日,版本 v1.0.3
|
||||
@@ -62,6 +65,9 @@
|
||||
|
||||
****
|
||||
|
||||
#### 2025年12月15日,版本 v1.0.6
|
||||
- **1. 修复** CFST新版本下获取不到第一行 IP 的问题
|
||||
|
||||
#### 2021年12月17日,版本 v1.0.5
|
||||
- **1. 优化** [找不到满足条件的 IP 就一直循环测速] 功能,在指定下载测速下限时没有重新测速的问题(默认注释)
|
||||
|
||||
@@ -118,6 +124,9 @@
|
||||
|
||||
****
|
||||
|
||||
#### 2025年12月15日,版本 v1.0.6 (cfst_ddns.bat)
|
||||
- **1. 修复** CFST新版本下获取不到第一行 IP 的问题
|
||||
|
||||
#### 2024年10月06日,版本 v1.0.5
|
||||
- **1. 新增** 支持 API 令牌方式(相比 API 密钥这种全局权限的,API 令牌可以自由控制权限)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
:: --------------------------------------------------------------
|
||||
:: <09><>Ŀ: CloudflareSpeedTest <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD> 3Proxy
|
||||
:: <09>汾: 1.0.5
|
||||
:: <09>汾: 1.0.6
|
||||
:: <09><><EFBFBD><EFBFBD>: XIU2
|
||||
:: <09><>Ŀ: https://github.com/XIU2/CloudflareSpeedTest
|
||||
:: --------------------------------------------------------------
|
||||
@@ -67,13 +67,11 @@ if not exist result_3proxy.txt (
|
||||
)
|
||||
|
||||
:: <20><>ȡ<EFBFBD><C8A1>һ<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD> IP
|
||||
for /f "tokens=1 delims=," %%i in (result_3proxy.txt) do (
|
||||
set /a n+=1
|
||||
If !n!==2 (
|
||||
set bestip=%%i
|
||||
goto :END
|
||||
)
|
||||
for /f "skip=1 tokens=1 delims=," %%i in ('more result_3proxy.txt') do (
|
||||
SET bestip=%%i
|
||||
goto :END
|
||||
)
|
||||
|
||||
:END
|
||||
|
||||
:: <20>жϸոջ<D5B8>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20>Ƿ<EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><D5A3>Լ<EFBFBD><D4BC>Ƿ<EFBFBD><C7B7>;<EFBFBD> IP һ<><D2BB>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
:: --------------------------------------------------------------
|
||||
:: 项目: CloudflareSpeedTest 自动更新域名解析记录
|
||||
:: 版本: 1.0.5
|
||||
:: 版本: 1.0.6
|
||||
:: 作者: XIU2
|
||||
:: 项目: https://github.com/XIU2/CloudflareSpeedTest
|
||||
:: --------------------------------------------------------------
|
||||
@@ -17,29 +17,26 @@ if not exist result_ddns.txt (
|
||||
goto :END
|
||||
)
|
||||
|
||||
for /f "tokens=1 delims=," %%i in (result_ddns.txt) do (
|
||||
Set /a n+=1
|
||||
If !n!==2 (
|
||||
Echo %%i
|
||||
if "%%i"=="" (
|
||||
echo.
|
||||
echo CFST 测速结果 IP 数量为 0,跳过下面步骤...
|
||||
goto :END
|
||||
)
|
||||
:: API 密钥方式(全局权限)
|
||||
curl -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/域名解析记录ID" ^
|
||||
-H "X-Auth-Email: 账号邮箱" ^
|
||||
-H "X-Auth-Key: 前面获取的 API 密钥" ^
|
||||
-H "Content-Type: application/json" ^
|
||||
--data "{\"type\":\"A\",\"name\":\"完整域名\",\"content\":\"%%i\",\"ttl\":1,\"proxied\":true}"
|
||||
:: API 令牌方式(自定义权限),如果要使用这种方式,可以把上面的删除或注释,然后把下面的行首 "::" 注释符删除即可。
|
||||
:: curl -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/域名解析记录ID" ^
|
||||
:: -H "Authorization: Bearer 前面获取的 API 令牌" ^
|
||||
:: -H "Content-Type: application/json" ^
|
||||
:: --data "{\"type\":\"A\",\"name\":\"完整域名\",\"content\":\"%%i\",\"ttl\":1,\"proxied\":true}"
|
||||
|
||||
for /f "skip=1 tokens=1 delims=," %%i in (result_ddns.txt) do (
|
||||
Echo %%i
|
||||
if "%%i"=="" (
|
||||
echo.
|
||||
echo CFST 测速结果 IP 数量为 0,跳过下面步骤...
|
||||
goto :END
|
||||
)
|
||||
:: API 密钥方式(全局权限)
|
||||
curl -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/域名解析记录ID" ^
|
||||
-H "X-Auth-Email: 账号邮箱" ^
|
||||
-H "X-Auth-Key: 前面获取的 API 密钥" ^
|
||||
-H "Content-Type: application/json" ^
|
||||
--data "{\"type\":\"A\",\"name\":\"完整域名\",\"content\":\"%%i\",\"ttl\":1,\"proxied\":true}"
|
||||
:: API 令牌方式(自定义权限),如果要使用这种方式,可以把上面的删除或注释,然后把下面的行首 "::" 注释符删除即可。
|
||||
:: curl -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/域名解析记录ID" ^
|
||||
:: -H "Authorization: Bearer 前面获取的 API 令牌" ^
|
||||
:: -H "Content-Type: application/json" ^
|
||||
:: --data "{\"type\":\"A\",\"name\":\"完整域名\",\"content\":\"%%i\",\"ttl\":1,\"proxied\":true}"
|
||||
|
||||
goto :END
|
||||
)
|
||||
:END
|
||||
pause
|
||||
@@ -1,6 +1,6 @@
|
||||
:: --------------------------------------------------------------
|
||||
:: <09><>Ŀ: CloudflareSpeedTest <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD> Hosts
|
||||
:: <09>汾: 1.0.4
|
||||
:: <09>汾: 1.0.5
|
||||
:: <09><><EFBFBD><EFBFBD>: XIU2
|
||||
:: <09><>Ŀ: https://github.com/XIU2/CloudflareSpeedTest
|
||||
:: --------------------------------------------------------------
|
||||
@@ -67,13 +67,11 @@ if not exist result_hosts.txt (
|
||||
)
|
||||
|
||||
:: <20><>ȡ<EFBFBD><C8A1>һ<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD> IP
|
||||
for /f "tokens=1 delims=," %%i in (result_hosts.txt) do (
|
||||
SET /a n+=1
|
||||
If !n!==2 (
|
||||
SET bestip=%%i
|
||||
goto :END
|
||||
)
|
||||
for /f "skip=1 tokens=1 delims=," %%i in ('more result_hosts.txt') do (
|
||||
SET bestip=%%i
|
||||
goto :END
|
||||
)
|
||||
|
||||
:END
|
||||
|
||||
:: <20>жϸոջ<D5B8>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20>Ƿ<EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><D5A3>Լ<EFBFBD><D4BC>Ƿ<EFBFBD><C7B7>;<EFBFBD> IP һ<><D2BB>
|
||||
|
||||
@@ -53,19 +53,19 @@ func TestDownloadSpeed(ipSet utils.PingDelaySet) (speedSet utils.DownloadSpeedSe
|
||||
if Disable {
|
||||
return utils.DownloadSpeedSet(ipSet)
|
||||
}
|
||||
if len(ipSet) <= 0 { // IP数组长度(IP数量) 大于 0 时才会继续下载测速
|
||||
fmt.Println("\n\033[33m[信息] 延迟测速结果 IP 数量为 0,跳过下载测速。\033[0m")
|
||||
if len(ipSet) <= 0 { // IP 数组长度(IP数量) 大于 0 时才会继续下载测速
|
||||
utils.Yellow.Println("[信息] 延迟测速结果 IP 数量为 0,跳过下载测速。")
|
||||
return
|
||||
}
|
||||
testNum := TestCount
|
||||
if len(ipSet) < TestCount || MinSpeed > 0 { // 如果IP数组长度(IP数量) 小于下载测速数量(-dn),则次数修正为IP数
|
||||
testNum := TestCount // 等待下载测速的队列数量 先默认等于 下载测速数量(-dn)
|
||||
if len(ipSet) < TestCount || MinSpeed > 0 { // 如果延迟测速并过滤后的 IP 数组长度(IP数量) 小于 下载测速数量(-dn),(即 -dn 预期数量是不够的),或者指定了 下载测速下限 (-sl) 条件(这就可能要全部下载测速一遍,直到找齐预期数量或测完为止),则 等待下载测速的队列数量 修正为 IP 数量
|
||||
testNum = len(ipSet)
|
||||
}
|
||||
if testNum < TestCount {
|
||||
if testNum < TestCount { // 如果 等待下载测速的队列数量 小于 下载测速数量(-dn),(显然 -dn 预期数量是不够的),所以 下载测速数量(-dn)修正为 等待下载测速的队列数量
|
||||
TestCount = testNum
|
||||
}
|
||||
|
||||
fmt.Printf("\033[34m开始下载测速(下限:%.2f MB/s, 数量:%d, 队列:%d)\033[0m\n", MinSpeed, TestCount, testNum)
|
||||
utils.Cyan.Printf("开始下载测速(下限:%.2f MB/s, 数量:%d, 队列:%d)\n", MinSpeed, TestCount, testNum)
|
||||
// 控制 下载测速进度条 与 延迟测速进度条 长度一致(强迫症)
|
||||
bar_a := len(strconv.Itoa(len(ipSet)))
|
||||
bar_b := " "
|
||||
@@ -89,10 +89,10 @@ func TestDownloadSpeed(ipSet utils.PingDelaySet) (speedSet utils.DownloadSpeedSe
|
||||
}
|
||||
}
|
||||
bar.Done()
|
||||
if MinSpeed == 0.00 { // 如果没有设置下载速度下限,则直接返回所有测速数据
|
||||
if MinSpeed == 0.00 { // 如果没有指定下载速度下限,则直接返回所有测速数据
|
||||
speedSet = utils.DownloadSpeedSet(ipSet)
|
||||
} else if utils.Debug && len(speedSet) == 0 { // 如果设置了下载速度下限,且是调试模式下,且没有找到任何一个满足条件的 IP 时,返回所有测速数据,供用户查看当前的测速结果,以便适当调低预期测速条件
|
||||
fmt.Println("\033[33m[调试] 没有满足 下载速度下限 条件的 IP,忽略条件返回所有测速数据(方便下次测速时调整条件)。\033[0m")
|
||||
} else if utils.Debug && len(speedSet) == 0 { // 如果指定了下载速度下限,且是调试模式下,且没有找到任何一个满足条件的 IP 时,返回所有测速数据,供用户查看当前的测速结果,以便适当调低预期测速条件
|
||||
utils.Yellow.Println("[调试] 没有满足 下载速度下限 条件的 IP,忽略条件返回所有测速数据(方便下次测速时调整条件)。")
|
||||
speedSet = utils.DownloadSpeedSet(ipSet)
|
||||
}
|
||||
// 按速度排序
|
||||
@@ -122,15 +122,15 @@ func printDownloadDebugInfo(ip *net.IPAddr, err error, statusCode int, url, last
|
||||
}
|
||||
if url != finalURL { // 如果 URL 和最终地址不一致,说明有重定向,是该重定向后的地址引起的错误
|
||||
if statusCode > 0 { // 如果状态码大于 0,说明是后续 HTTP 状态码引起的错误
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 下载测速终止,HTTP 状态码: %d, 下载测速地址: %s, 出错的重定向后地址: %s\033[0m\n", ip.String(), statusCode, url, finalURL)
|
||||
utils.Red.Printf("[调试] IP: %s, 下载测速终止,HTTP 状态码: %d, 下载测速地址: %s, 出错的重定向后地址: %s\n", ip.String(), statusCode, url, finalURL)
|
||||
} else {
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 下载测速失败,错误信息: %v, 下载测速地址: %s, 出错的重定向后地址: %s\033[0m\n", ip.String(), err, url, finalURL)
|
||||
utils.Red.Printf("[调试] IP: %s, 下载测速失败,错误信息: %v, 下载测速地址: %s, 出错的重定向后地址: %s\n", ip.String(), err, url, finalURL)
|
||||
}
|
||||
} else { // 如果 URL 和最终地址一致,说明没有重定向
|
||||
if statusCode > 0 { // 如果状态码大于 0,说明是后续 HTTP 状态码引起的错误
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 下载测速终止,HTTP 状态码: %d, 下载测速地址: %s\033[0m\n", ip.String(), statusCode, url)
|
||||
utils.Red.Printf("[调试] IP: %s, 下载测速终止,HTTP 状态码: %d, 下载测速地址: %s\n", ip.String(), statusCode, url)
|
||||
} else {
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 下载测速失败,错误信息: %v, 下载测速地址: %s\033[0m\n", ip.String(), err, url)
|
||||
utils.Red.Printf("[调试] IP: %s, 下载测速失败,错误信息: %v, 下载测速地址: %s\n", ip.String(), err, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,7 +145,7 @@ func downloadHandler(ip *net.IPAddr) (float64, string) {
|
||||
lastRedirectURL = req.URL.String() // 记录每次重定向的目标,以便在访问错误时输出
|
||||
if len(via) > 10 { // 限制最多重定向 10 次
|
||||
if utils.Debug { // 调试模式下,输出更多信息
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 下载测速地址重定向次数过多,终止测速,下载测速地址: %s\033[0m\n", ip.String(), req.URL.String())
|
||||
utils.Red.Printf("[调试] IP: %s, 下载测速地址重定向次数过多,终止测速,下载测速地址: %s\n", ip.String(), req.URL.String())
|
||||
}
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
@@ -158,7 +158,7 @@ func downloadHandler(ip *net.IPAddr) (float64, string) {
|
||||
req, err := http.NewRequest("GET", URL, nil)
|
||||
if err != nil {
|
||||
if utils.Debug { // 调试模式下,输出更多信息
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 下载测速请求创建失败,错误信息: %v, 下载测速地址: %s\033[0m\n", ip.String(), err, URL)
|
||||
utils.Red.Printf("[调试] IP: %s, 下载测速请求创建失败,错误信息: %v, 下载测速地址: %s\n", ip.String(), err, URL)
|
||||
}
|
||||
return 0.0, ""
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package task
|
||||
|
||||
import (
|
||||
//"crypto/tls"
|
||||
"fmt"
|
||||
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
@@ -44,7 +44,7 @@ func (p *Ping) httping(ip *net.IPAddr) (int, time.Duration, string) {
|
||||
request, err := http.NewRequest(http.MethodHead, URL, nil)
|
||||
if err != nil {
|
||||
if utils.Debug { // 调试模式下,输出更多信息
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 延迟测速请求创建失败,错误信息: %v, 测速地址: %s\033[0m\n", ip.String(), err, URL)
|
||||
utils.Red.Printf("[调试] IP: %s, 延迟测速请求创建失败,错误信息: %v, 测速地址: %s\n", ip.String(), err, URL)
|
||||
}
|
||||
return 0, 0, ""
|
||||
}
|
||||
@@ -52,7 +52,7 @@ func (p *Ping) httping(ip *net.IPAddr) (int, time.Duration, string) {
|
||||
response, err := hc.Do(request)
|
||||
if err != nil {
|
||||
if utils.Debug { // 调试模式下,输出更多信息
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 延迟测速失败,错误信息: %v, 测速地址: %s\033[0m\n", ip.String(), err, URL)
|
||||
utils.Red.Printf("[调试] IP: %s, 延迟测速失败,错误信息: %v, 测速地址: %s\n", ip.String(), err, URL)
|
||||
}
|
||||
return 0, 0, ""
|
||||
}
|
||||
@@ -63,14 +63,14 @@ func (p *Ping) httping(ip *net.IPAddr) (int, time.Duration, string) {
|
||||
if HttpingStatusCode == 0 || HttpingStatusCode < 100 && HttpingStatusCode > 599 {
|
||||
if response.StatusCode != 200 && response.StatusCode != 301 && response.StatusCode != 302 {
|
||||
if utils.Debug { // 调试模式下,输出更多信息
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 延迟测速终止,HTTP 状态码: %d, 测速地址: %s\033[0m\n", ip.String(), response.StatusCode, URL)
|
||||
utils.Red.Printf("[调试] IP: %s, 延迟测速终止,HTTP 状态码: %d, 测速地址: %s\n", ip.String(), response.StatusCode, URL)
|
||||
}
|
||||
return 0, 0, ""
|
||||
}
|
||||
} else {
|
||||
if response.StatusCode != HttpingStatusCode {
|
||||
if utils.Debug { // 调试模式下,输出更多信息
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 延迟测速终止,HTTP 状态码: %d, 指定的 HTTP 状态码 %d, 测速地址: %s\033[0m\n", ip.String(), response.StatusCode, HttpingStatusCode, URL)
|
||||
utils.Red.Printf("[调试] IP: %s, 延迟测速终止,HTTP 状态码: %d, 指定的 HTTP 状态码 %d, 测速地址: %s\n", ip.String(), response.StatusCode, HttpingStatusCode, URL)
|
||||
}
|
||||
return 0, 0, ""
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func (p *Ping) httping(ip *net.IPAddr) (int, time.Duration, string) {
|
||||
colo = p.filterColo(colo)
|
||||
if colo == "" { // 没有匹配到地区码或不符合指定地区则直接结束该 IP 测试
|
||||
if utils.Debug { // 调试模式下,输出更多信息
|
||||
fmt.Printf("\033[31m[调试] IP: %s, 地区码不匹配: %s\033[0m\n", ip.String(), colo)
|
||||
utils.Red.Printf("[调试] IP: %s, 地区码不匹配: %s\n", ip.String(), colo)
|
||||
}
|
||||
return 0, 0, ""
|
||||
}
|
||||
|
||||
@@ -64,9 +64,9 @@ func (p *Ping) Run() utils.PingDelaySet {
|
||||
return p.csv
|
||||
}
|
||||
if Httping {
|
||||
fmt.Printf("\033[34m开始延迟测速(模式:HTTP, 端口:%d, 范围:%v ~ %v ms, 丢包:%.2f)\033[0m\n", TCPPort, utils.InputMinDelay.Milliseconds(), utils.InputMaxDelay.Milliseconds(), utils.InputMaxLossRate)
|
||||
utils.Cyan.Printf("开始延迟测速(模式:HTTP, 端口:%d, 范围:%v ~ %v ms, 丢包:%.2f)\n", TCPPort, utils.InputMinDelay.Milliseconds(), utils.InputMaxDelay.Milliseconds(), utils.InputMaxLossRate)
|
||||
} else {
|
||||
fmt.Printf("\033[34m开始延迟测速(模式:TCP, 端口:%d, 范围:%v ~ %v ms, 丢包:%.2f)\033[0m\n", TCPPort, utils.InputMinDelay.Milliseconds(), utils.InputMaxDelay.Milliseconds(), utils.InputMaxLossRate)
|
||||
utils.Cyan.Printf("开始延迟测速(模式:TCP, 端口:%d, 范围:%v ~ %v ms, 丢包:%.2f)\n", TCPPort, utils.InputMinDelay.Milliseconds(), utils.InputMaxDelay.Milliseconds(), utils.InputMaxLossRate)
|
||||
}
|
||||
for _, ip := range p.ips {
|
||||
p.wg.Add(1)
|
||||
|
||||
16
utils/color.go
Normal file
16
utils/color.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
// 由专业的库来处理多平台的颜色输出效果
|
||||
var (
|
||||
Red = color.New(color.FgRed) // 红色 31
|
||||
Green = color.New(color.FgGreen) // 绿色 32
|
||||
Yellow = color.New(color.FgYellow) // 黄色 33
|
||||
Blue = color.New(color.FgBlue, color.Bold) // 蓝色 34
|
||||
Magenta = color.New(color.FgMagenta) // 紫红色 35
|
||||
Cyan = color.New(color.FgHiCyan, color.Bold) // 青色 36
|
||||
White = color.New(color.FgWhite) // 白色 37
|
||||
)
|
||||
@@ -176,16 +176,16 @@ func (s DownloadSpeedSet) Print() {
|
||||
if len(dateString) < PrintNum { // 如果IP数组长度(IP数量) 小于 打印次数,则次数改为IP数量
|
||||
PrintNum = len(dateString)
|
||||
}
|
||||
headFormat := "\033[34m%-16s%-5s%-5s%-5s%-6s%-12s%-5s\033[0m\n"
|
||||
headFormat := "%-16s%-5s%-5s%-5s%-6s%-12s%-5s\n"
|
||||
dataFormat := "%-18s%-8s%-8s%-8s%-10s%-16s%-8s\n"
|
||||
for i := 0; i < PrintNum; i++ { // 如果要输出的 IP 中包含 IPv6,那么就需要调整一下间隔
|
||||
if len(dateString[i][0]) > 15 {
|
||||
headFormat = "\033[34m%-40s%-5s%-5s%-5s%-6s%-12s%-5s\033[0m\n"
|
||||
headFormat = "%-40s%-5s%-5s%-5s%-6s%-12s%-5s\n"
|
||||
dataFormat = "%-42s%-8s%-8s%-8s%-10s%-16s%-8s\n"
|
||||
break
|
||||
}
|
||||
}
|
||||
fmt.Printf(headFormat, "IP 地址", "已发送", "已接收", "丢包率", "平均延迟", "下载速度(MB/s)", "地区码")
|
||||
Cyan.Printf(headFormat, "IP 地址", "已发送", "已接收", "丢包率", "平均延迟", "下载速度(MB/s)", "地区码")
|
||||
for i := 0; i < PrintNum; i++ {
|
||||
fmt.Printf(dataFormat, dateString[i][0], dateString[i][1], dateString[i][2], dateString[i][3], dateString[i][4], dateString[i][5], dateString[i][6])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user