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:
@@ -11,5 +11,6 @@ require (
|
|||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.10 // indirect
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
golang.org/x/sys v0.47.0 // indirect
|
golang.org/x/sys v0.47.0 // indirect
|
||||||
|
golang.org/x/text v0.41.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
|||||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
|
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
|
||||||
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
|
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
|
||||||
|
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
|
||||||
|
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package discovery
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -10,6 +11,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"auto-check/pkg/model"
|
"auto-check/pkg/model"
|
||||||
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
|
"golang.org/x/text/transform"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scanner 网段扫描器(并发 ping 探测)
|
// 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)
|
cmd := exec.CommandContext(ctx, "ping", "-n", "1", "-w", fmt.Sprintf("%d", pingWait), ip)
|
||||||
out, err := cmd.Output()
|
out, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Printf(" [-] %s ping err=%v\n", ip, err)
|
||||||
return false
|
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 {
|
func parsePingReply(out string) bool {
|
||||||
for _, line := range strings.Split(out, "\n") {
|
for _, line := range strings.Split(out, "\n") {
|
||||||
l := strings.ToLower(strings.TrimSpace(line))
|
l := strings.ToLower(strings.TrimSpace(line))
|
||||||
// Windows: "Packets: Sent = 1, Received = 1, Lost = 0"
|
// 提取关键字后的接收数,定位到 '=' 之后
|
||||||
if strings.Contains(l, "received =") {
|
kw := "received ="
|
||||||
i := strings.Index(l, "received =")
|
idx := strings.Index(l, kw)
|
||||||
n := strings.TrimSpace(l[i+len("received ="):])
|
if idx < 0 {
|
||||||
// 取数字前缀
|
kw = "已接收 ="
|
||||||
cnt := 0
|
idx = strings.Index(l, kw)
|
||||||
for _, c := range n {
|
|
||||||
if c < '0' || c > '9' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cnt = cnt*10 + int(c-'0')
|
|
||||||
}
|
|
||||||
return cnt >= 1
|
|
||||||
}
|
}
|
||||||
|
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
|
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)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user