fix(discovery): support Chinese ping output and decode GBK

- parsePingReply now matches both 'received =' (English) and 'received =' (Chinese) so devices are detected correctly on non-English Windows

- decode ping stdout from GBK to UTF-8

- remove raw ping log output

- add golang.org/x/text dependency
This commit is contained in:
12600k-rog-d4
2026-08-13 02:05:32 +08:00
parent 06908a2fbc
commit ab81cee9b0
3 changed files with 46 additions and 15 deletions

View File

@@ -3,6 +3,7 @@ package discovery
import (
"context"
"fmt"
"io"
"net"
"os/exec"
"strings"
@@ -10,6 +11,8 @@ import (
"time"
"auto-check/pkg/model"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
)
// Scanner 网段扫描器(并发 ping 探测)
@@ -103,29 +106,43 @@ func (s *Scanner) ping(ip string) bool {
cmd := exec.CommandContext(ctx, "ping", "-n", "1", "-w", fmt.Sprintf("%d", pingWait), ip)
out, err := cmd.Output()
if err != nil {
fmt.Printf(" [-] %s ping err=%v\n", ip, err)
return false
}
return parsePingReply(string(out))
// Windows 下 ping 输出为 GBK 编码,解码为 UTF-8 后再解析
text := decodeGBK(out)
return parsePingReply(text)
}
// parsePingReply 判断 ping 输出是否表示存活
// parsePingReply 判断 ping 输出是否表示存活
// 兼容中英文 Windows 输出:英文 "Received = 1" / 中文 "已接收 = 1"。
// 匹配接收数关键字后取其后数字,>=1 即视为存活。
func parsePingReply(out string) bool {
for _, line := range strings.Split(out, "\n") {
l := strings.ToLower(strings.TrimSpace(line))
// Windows: "Packets: Sent = 1, Received = 1, Lost = 0"
if strings.Contains(l, "received =") {
i := strings.Index(l, "received =")
n := strings.TrimSpace(l[i+len("received ="):])
// 取数字前缀
cnt := 0
for _, c := range n {
if c < '0' || c > '9' {
break
}
cnt = cnt*10 + int(c-'0')
}
return cnt >= 1
// 提取关键字后的接收数,定位到 '=' 之后
kw := "received ="
idx := strings.Index(l, kw)
if idx < 0 {
kw = "已接收 ="
idx = strings.Index(l, kw)
}
if idx < 0 {
continue
}
eq := strings.Index(l[idx:], "=")
if eq < 0 {
continue
}
n := strings.TrimSpace(l[idx+eq+1:])
cnt := 0
for _, c := range n {
if c < '0' || c > '9' {
break
}
cnt = cnt*10 + int(c-'0')
}
return cnt >= 1
}
return false
}
@@ -139,3 +156,14 @@ func inc(ip net.IP) {
}
}
}
// decodeGBK 将 GBK 编码字节转为 UTF-8 字符串Windows ping 输出为 GBK
// 若解码失败则原样返回。
func decodeGBK(b []byte) string {
r := transform.NewReader(strings.NewReader(string(b)), simplifiedchinese.GBK.NewDecoder())
out, err := io.ReadAll(r)
if err != nil {
return string(b)
}
return string(out)
}