From b9622651686b30801100dbaa96e234765cb1468a Mon Sep 17 00:00:00 2001 From: yoyo Date: Wed, 17 Dec 2025 19:16:39 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=20TCPing=20?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=9A=84=E7=9B=AE=E6=A0=87=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 改进了 TCPing 任务中对 host:port 格式的解析,支持 IPv6 地址格式并默认使用端口 80。 - 移除了不必要的空行以提升代码可读性。 - 更新了安装脚本,移除了不再使用的镜像源。 --- install.sh | 2 - internal/continuous/tcping.go | 52 +++++++++++++++++------ internal/handler/tcping.go | 77 +++++++++++++++++++++++------------ 3 files changed, 92 insertions(+), 39 deletions(-) diff --git a/install.sh b/install.sh index 9204568..2987b74 100755 --- a/install.sh +++ b/install.sh @@ -96,7 +96,6 @@ detect_fastest_mirror() { # Ubuntu/Debian 镜像源列表 UBUNTU_MIRRORS=( - "mirrors.tuna.tsinghua.edu.cn" "mirrors.huaweicloud.com" "mirrors.163.com" "archive.ubuntu.com" @@ -104,7 +103,6 @@ detect_fastest_mirror() { # CentOS/RHEL 镜像源列表 CENTOS_MIRRORS=( - "mirrors.tuna.tsinghua.edu.cn" "mirrors.huaweicloud.com" ) diff --git a/internal/continuous/tcping.go b/internal/continuous/tcping.go index 8cfc585..e4effd0 100644 --- a/internal/continuous/tcping.go +++ b/internal/continuous/tcping.go @@ -28,14 +28,43 @@ type TCPingTask struct { } func NewTCPingTask(taskID, target string, interval, maxDuration time.Duration) (*TCPingTask, error) { - // 解析host:port - parts := strings.Split(target, ":") - if len(parts) != 2 { - return nil, fmt.Errorf("无效的target格式,需要 host:port") + // 解析host:port,如果没有端口则默认80 + var host string + var portStr string + var port int + + // 检查是否是IPv6格式(如 [::1]:8080) + if strings.HasPrefix(target, "[") { + // IPv6格式 + closeBracket := strings.LastIndex(target, "]") + if closeBracket == -1 { + return nil, fmt.Errorf("无效的target格式,IPv6地址格式应为 [host]:port") + } + host = target[1:closeBracket] + if closeBracket+1 < len(target) && target[closeBracket+1] == ':' { + portStr = target[closeBracket+2:] + } else { + portStr = "80" // 默认端口 + } + } else { + // 普通格式 host:port 或 host + lastColonIndex := strings.LastIndex(target, ":") + if lastColonIndex == -1 { + // 没有冒号,使用默认端口80 + host = target + portStr = "80" + } else { + host = target[:lastColonIndex] + portStr = target[lastColonIndex+1:] + // 如果端口部分为空,使用默认端口80 + if portStr == "" { + portStr = "80" + } + } } - host := parts[0] - port, err := strconv.Atoi(parts[1]) + var err error + port, err = strconv.Atoi(portStr) if err != nil { return nil, fmt.Errorf("无效的端口: %v", err) } @@ -80,10 +109,10 @@ func (t *TCPingTask) Start(ctx context.Context, resultCallback func(result map[s if !isRunning { return } - + // 执行tcping测试(每次测试完成后立即返回结果) result := t.executeTCPing() - + // 再次检查任务是否已停止(执行完成后) t.mu.RLock() isRunning = t.IsRunning @@ -91,7 +120,7 @@ func (t *TCPingTask) Start(ctx context.Context, resultCallback func(result map[s if !isRunning { return } - + if resultCallback != nil { resultCallback(result) } @@ -117,7 +146,7 @@ func (t *TCPingTask) Stop() { } t.IsRunning = false t.mu.Unlock() - + // 关闭停止通道 select { case <-t.StopCh: @@ -125,7 +154,7 @@ func (t *TCPingTask) Stop() { default: close(t.StopCh) } - + t.logger.Info("TCPing任务已停止", zap.String("task_id", t.TaskID)) } @@ -185,4 +214,3 @@ func (t *TCPingTask) executeTCPing() map[string]interface{} { "ip": targetIP, } } - diff --git a/internal/handler/tcping.go b/internal/handler/tcping.go index a679cab..546fac7 100644 --- a/internal/handler/tcping.go +++ b/internal/handler/tcping.go @@ -16,27 +16,55 @@ func handleTCPing(c *gin.Context, url string, params map[string]interface{}) { seq = seqVal } - // 解析host:port格式 - parts := strings.Split(url, ":") - if len(parts) != 2 { - c.JSON(200, gin.H{ - "seq": seq, - "type": "ceTCPing", - "url": url, - "error": "格式错误,需要 host:port", - }) - return + // 解析host:port格式,如果没有端口则默认80 + var host string + var portStr string + var port int + + // 检查是否是IPv6格式(如 [::1]:8080) + if strings.HasPrefix(url, "[") { + // IPv6格式 + closeBracket := strings.LastIndex(url, "]") + if closeBracket == -1 { + c.JSON(200, gin.H{ + "seq": seq, + "type": "ceTCPing", + "url": url, + "error": "格式错误,IPv6地址格式应为 [host]:port", + }) + return + } + host = url[1:closeBracket] + if closeBracket+1 < len(url) && url[closeBracket+1] == ':' { + portStr = url[closeBracket+2:] + } else { + portStr = "80" // 默认端口 + } + } else { + // 普通格式 host:port 或 host + lastColonIndex := strings.LastIndex(url, ":") + if lastColonIndex == -1 { + // 没有冒号,使用默认端口80 + host = url + portStr = "80" + } else { + host = url[:lastColonIndex] + portStr = url[lastColonIndex+1:] + // 如果端口部分为空,使用默认端口80 + if portStr == "" { + portStr = "80" + } + } } - host := parts[0] - portStr := parts[1] - port, err := strconv.Atoi(portStr) + var err error + port, err = strconv.Atoi(portStr) if err != nil { c.JSON(200, gin.H{ - "seq": seq, - "type": "ceTCPing", - "url": url, - "error": "端口格式错误", + "seq": seq, + "type": "ceTCPing", + "url": url, + "error": "端口格式错误", }) return } @@ -131,17 +159,17 @@ func handleTCPing(c *gin.Context, url string, params map[string]interface{}) { // 返回格式和PING一致 result := gin.H{ - "seq": seq, - "type": "ceTCPing", - "url": url, - "ip": primaryIP, - "host": host, - "port": port, + "seq": seq, + "type": "ceTCPing", + "url": url, + "ip": primaryIP, + "host": host, + "port": port, "packets_total": strconv.Itoa(packetsTotal), "packets_recv": strconv.Itoa(packetsRecv), "packets_losrat": packetsLosrat, // float64类型,百分比值(如10.5表示10.5%) } - + // 时间字段:如果是-1(全部失败),返回字符串"-",否则返回float64 if timeMin < 0 { result["time_min"] = "-" @@ -160,4 +188,3 @@ func handleTCPing(c *gin.Context, url string, params map[string]interface{}) { c.JSON(200, result) } -