update: params
This commit is contained in:
20
README.md
20
README.md
@@ -1,33 +1,33 @@
|
|||||||
# Tcping GO
|
# Tcping GO
|
||||||
|
|
||||||
一个使用go写的小工具,用于检测TCP端口是否开放
|
一个使用 Golang 写的小工具,用于检测TCP端口是否开放
|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|
||||||
你可以简单的测试一个地址的某个端口是否开放,可以使用域名或者IP地址,默认测试该地址的80端口
|
你可以简单的测试一个域名(或 IP 地址)的某个端口是否开放,默认测试 80 端口
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
tcping www.baidu.com
|
tcping www.qq.com
|
||||||
使用 www.qq.com 的 A 记录: 175.27.8.138
|
使用 www.qq.com 的 A 记录: 175.27.8.138
|
||||||
[1] 来自 175.27.8.138:80 的响应: 时间=29.256ms
|
[1] 来自 175.27.8.138:80 的响应: 时间=29.256ms
|
||||||
[2] 来自 175.27.8.138:80 的响应: 时间=29.086ms
|
[2] 来自 175.27.8.138:80 的响应: 时间=29.086ms
|
||||||
[3] 来自 175.27.8.138:80 的响应: 时间=37.761ms
|
[3] 来自 175.27.8.138:80 的响应: 时间=37.761ms
|
||||||
[4] 来自 175.27.8.138:80 的响应: 时间=30.259ms
|
[4] 来自 175.27.8.138:80 的响应: 时间=30.259ms
|
||||||
|
|
||||||
测试完成,成功次数: 4/4
|
测试完成,成功 4/4 (100.00%)
|
||||||
```
|
```
|
||||||
|
|
||||||
使用 `-p` 指定端口号,如下
|
也可以指定测试端口号,跟随在域名或 IP 地址后面
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
tcping www.qq.com -p 443
|
tcping www.qq.com 443
|
||||||
使用 www.qq.com 的 A 记录: 175.27.8.138
|
使用 www.qq.com 的 A 记录: 175.27.8.138
|
||||||
[1] 来自 175.27.8.138:443 的响应: 时间=28.835ms
|
[1] 来自 175.27.8.138:443 的响应: 时间=28.835ms
|
||||||
[2] 来自 175.27.8.138:443 的响应: 时间=27.419ms
|
[2] 来自 175.27.8.138:443 的响应: 时间=27.419ms
|
||||||
[3] 来自 175.27.8.138:443 的响应: 时间=44.382ms
|
[3] 来自 175.27.8.138:443 的响应: 时间=44.382ms
|
||||||
[4] 来自 175.27.8.138:443 的响应: 时间=28.356ms
|
[4] 来自 175.27.8.138:443 的响应: 时间=28.356ms
|
||||||
|
|
||||||
测试完成,成功次数: 4/4
|
测试完成,成功 4/4 (100.00%)
|
||||||
```
|
```
|
||||||
|
|
||||||
使用 `-6` 指定使用IPv6(仅对域名有效)
|
使用 `-6` 指定使用IPv6(仅对域名有效)
|
||||||
@@ -40,11 +40,13 @@ tcping www.qq.com -6
|
|||||||
[3] 来自 [240e:97c:2f:1::5c]:80 的响应: 时间=30.856ms
|
[3] 来自 [240e:97c:2f:1::5c]:80 的响应: 时间=30.856ms
|
||||||
[4] 来自 [240e:97c:2f:1::5c]:80 的响应: 时间=30.275ms
|
[4] 来自 [240e:97c:2f:1::5c]:80 的响应: 时间=30.275ms
|
||||||
|
|
||||||
测试完成,成功次数: 4/4
|
测试完成,成功 4/4 (100.00%)
|
||||||
```
|
```
|
||||||
|
|
||||||
使用 `-c` 指定测试次数,默认为4次
|
使用 `-c` 指定测试次数,默认为4次
|
||||||
|
|
||||||
使用 `-t` 指定超时时间,默认为2秒
|
使用 `-s` 指定超时时间,默认为2秒
|
||||||
|
|
||||||
|
使用 `-t` 来启用无限次测试模式
|
||||||
|
|
||||||
使用 `-f` 来启用快速模式,降低两次成功测试之间的间隔时间
|
使用 `-f` 来启用快速模式,降低两次成功测试之间的间隔时间
|
||||||
|
|||||||
56
main.go
56
main.go
@@ -5,6 +5,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -28,15 +29,13 @@ func main() {
|
|||||||
|
|
||||||
version := "1.0.0"
|
version := "1.0.0"
|
||||||
|
|
||||||
// 设置命令行参数
|
showHelp := flag.BoolP("help", "h", false, "Show help")
|
||||||
showHelp := flag.BoolP("help", "h", false, "显示帮助信息")
|
showVersion := flag.BoolP("version", "v", false, "Show version")
|
||||||
showVersion := flag.BoolP("version", "v", false, "显示版本信息")
|
flag.IntVarP(&count, "count", "c", 4, "Number of probes, default 4")
|
||||||
flag.IntVarP(&port, "port", "p", 80, "端口,默认为80")
|
flag.DurationVarP(&timeoutDuration, "timeout", "s", 2*time.Second, "Timeout, default 2s")
|
||||||
flag.IntVarP(&count, "count", "c", 4, "测试次数,默认为4次")
|
flag.BoolVarP(&infinite, "infinite", "t", false, "Infinite probes")
|
||||||
flag.DurationVarP(&timeoutDuration, "timeout", "s", 2*time.Second, "超时时间,默认为2秒")
|
flag.BoolVarP(&ipv6, "ipv6", "6", false, "Use IPv6; requires domain name")
|
||||||
flag.BoolVarP(&infinite, "infinite", "t", false, "无限次测试")
|
flag.BoolVarP(&fast, "fast", "f", false, "Fast mode; reduce delay between successful probes")
|
||||||
flag.BoolVarP(&ipv6, "ipv6", "6", false, "使用 IPv6,需搭配域名使用")
|
|
||||||
flag.BoolVarP(&fast, "fast", "f", false, "快速模式,降低每次成功测试之间的间隔")
|
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@@ -56,12 +55,20 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if port < 1 || port > 65535 {
|
hostname := args[0]
|
||||||
fmt.Println("端口号必须在1-65535之间")
|
port = 80
|
||||||
|
if len(args) >= 2 {
|
||||||
|
p, err := strconv.Atoi(args[1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Port must be an integer")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
port = p
|
||||||
|
}
|
||||||
|
if port < 1 || port > 65535 {
|
||||||
|
fmt.Println("Port must be between 1 and 65535")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
hostname := args[0]
|
|
||||||
|
|
||||||
// 设置信号捕获
|
// 设置信号捕获
|
||||||
stopped = false
|
stopped = false
|
||||||
@@ -74,7 +81,7 @@ func main() {
|
|||||||
// 解析域名
|
// 解析域名
|
||||||
ips, err := net.LookupIP(hostname)
|
ips, err := net.LookupIP(hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("解析 %s 失败: %s\n", hostname, err)
|
fmt.Printf("Failed to resolve %s: %s\n", hostname, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
record := "A"
|
record := "A"
|
||||||
@@ -83,10 +90,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
ip, err = filterIP(ips, ipv6)
|
ip, err = filterIP(ips, ipv6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("找不到 %s 的 %s 记录\n", hostname, record)
|
fmt.Printf("No %s record found for %s\n", record, hostname)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fmt.Printf("使用 %s 的 %s 记录: %s\n", hostname, record, ip)
|
fmt.Printf("Using %s %s record: %s\n", hostname, record, ip)
|
||||||
} else {
|
} else {
|
||||||
ip = hostname
|
ip = hostname
|
||||||
}
|
}
|
||||||
@@ -107,11 +114,11 @@ func main() {
|
|||||||
|
|
||||||
fmt.Printf("[%d] ", i+1)
|
fmt.Printf("[%d] ", i+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("测试到 %s 的连接失败: %s\n", address, "连接超时")
|
fmt.Printf("Connection to %s failed: %s\n", address, "timeout")
|
||||||
} else {
|
} else {
|
||||||
successCount++
|
successCount++
|
||||||
successDelay = append(successDelay, duration)
|
successDelay = append(successDelay, duration)
|
||||||
fmt.Printf("来自 %s 的响应: 时间=%s\n", address, fmt.Sprintf("%.3fms", float64(duration)/float64(time.Millisecond)))
|
fmt.Printf("Reply from %s: time=%s\n", address, fmt.Sprintf("%.3fms", float64(duration)/float64(time.Millisecond)))
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,20 +134,17 @@ func main() {
|
|||||||
done <- true
|
done <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// 等待信号或测试完成
|
|
||||||
select {
|
select {
|
||||||
case <-sigChan:
|
case <-sigChan:
|
||||||
fmt.Println("\n测试被用户中断")
|
fmt.Println("\nTest interrupted by user")
|
||||||
stopped = true
|
stopped = true
|
||||||
case <-done:
|
case <-done:
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打印统计结果
|
|
||||||
if !stopped {
|
if !stopped {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert duration to milliseconds
|
|
||||||
successDelayMs := make([]float64, len(successDelay))
|
successDelayMs := make([]float64, len(successDelay))
|
||||||
for i, delay := range successDelay {
|
for i, delay := range successDelay {
|
||||||
successDelayMs[i] = float64(delay) / float64(time.Millisecond)
|
successDelayMs[i] = float64(delay) / float64(time.Millisecond)
|
||||||
@@ -149,13 +153,17 @@ func main() {
|
|||||||
minDelay := 0.0
|
minDelay := 0.0
|
||||||
maxDelay := 0.0
|
maxDelay := 0.0
|
||||||
avgDelay := 0.0
|
avgDelay := 0.0
|
||||||
|
successRate := 0.0
|
||||||
|
|
||||||
if successCount > 0 {
|
if successCount > 0 {
|
||||||
minDelay = float64_min(successDelayMs)
|
minDelay = float64_min(successDelayMs)
|
||||||
maxDelay = float64_max(successDelayMs)
|
maxDelay = float64_max(successDelayMs)
|
||||||
avgDelay = float64_avg(successDelayMs)
|
avgDelay = float64_avg(successDelayMs)
|
||||||
}
|
}
|
||||||
fmt.Printf("测试完成,成功次数: %d/%d,最小=%.3fms,最大=%.3fms,平均=%.3fms\n", successCount, attemptCount, minDelay, maxDelay, avgDelay)
|
if attemptCount > 0 {
|
||||||
|
successRate = float64(successCount) / float64(attemptCount) * 100
|
||||||
|
}
|
||||||
|
fmt.Printf("Test finished, success %d/%d (%.2f%%)\nmin = %.3fms, max = %.3fms, avg = %.3fms\n", successCount, attemptCount, successRate, minDelay, maxDelay, avgDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterIP(ips []net.IP, ipv6 bool) (string, error) {
|
func filterIP(ips []net.IP, ipv6 bool) (string, error) {
|
||||||
@@ -172,7 +180,7 @@ func filterIP(ips []net.IP, ipv6 bool) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("找不到合适的IP地址")
|
return "", fmt.Errorf("no suitable IP address found")
|
||||||
}
|
}
|
||||||
|
|
||||||
func float64_min(array []float64) float64 {
|
func float64_min(array []float64) float64 {
|
||||||
|
|||||||
Reference in New Issue
Block a user