mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
80 lines
1.3 KiB
Go
80 lines
1.3 KiB
Go
package utils
|
|
|
|
import (
|
|
"errors"
|
|
"math/rand"
|
|
"net"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
type ICMPPingResult struct {
|
|
PacketsSent int
|
|
PacketsLoss int
|
|
AvgTimeMill int64
|
|
}
|
|
|
|
// RunICMPPingLoop unix 下的 ping
|
|
func RunICMPPingLoop(ip string, count int) (r ICMPPingResult) {
|
|
r = ICMPPingResult{
|
|
PacketsSent: count,
|
|
PacketsLoss: count,
|
|
AvgTimeMill: 9999,
|
|
}
|
|
if count <= 0 {
|
|
return
|
|
}
|
|
durs := make([]int64, 0, count)
|
|
for i := 0; i < count; i++ {
|
|
d, err := pingudp(ip)
|
|
if err == nil {
|
|
r.PacketsLoss--
|
|
durs = append(durs, d)
|
|
}
|
|
}
|
|
|
|
if len(durs) > 0 {
|
|
r.AvgTimeMill = 0
|
|
for _, d := range durs {
|
|
r.AvgTimeMill += d
|
|
}
|
|
if len(durs) > 1 {
|
|
r.AvgTimeMill /= int64(len(durs))
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func pingudp(ip string) (int64, error) {
|
|
var buf [256]byte
|
|
ch := make(chan error, 1)
|
|
|
|
port := rand.Intn(10000) + 50000
|
|
conn, err := net.Dial("udp", ip+":"+strconv.Itoa(port))
|
|
if err != nil {
|
|
return 9999, err
|
|
}
|
|
|
|
t := time.Now().UnixMilli()
|
|
|
|
_, err = conn.Write([]byte("fill"))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
go func() {
|
|
_, err := conn.Read(buf[:])
|
|
ch <- err
|
|
}()
|
|
select {
|
|
case <-time.NewTimer(time.Second * 4).C:
|
|
err = errors.New("timeout")
|
|
case err = <-ch:
|
|
}
|
|
|
|
if err != nil && err.Error() == "timeout" {
|
|
return 9999, err
|
|
}
|
|
return time.Now().UnixMilli() - t, nil
|
|
}
|