Files
CloudflareSpeedTest/tcping.go
2020-07-05 13:19:53 +08:00

88 lines
2.2 KiB
Go

package main
import (
"net"
"strconv"
"sync"
"time"
)
const defaultTcpPort = 443
const tcpConnectTimeout = time.Second * 1
const failTime = 4
//bool connectionSucceed float64 time
func tcping(ip net.IPAddr) (bool, float64) {
startTime := time.Now()
conn, err := net.DialTimeout("tcp", ip.String()+":"+strconv.Itoa(defaultTcpPort), tcpConnectTimeout)
if err != nil {
return false, 0
} else {
var endTime = time.Since(startTime)
var duration = float64(endTime.Microseconds()) / 1000.0
_ = conn.Close()
return true, duration
}
}
//pingReceived pingTotalTime
func checkConnection(ip net.IPAddr) (int, float64) {
pingRecv := 0
pingTime := 0.0
for i := 1; i <= failTime; i++ {
pingSucceed, pingTimeCurrent := tcping(ip)
if pingSucceed {
pingRecv++
pingTime += pingTimeCurrent
}
}
return pingRecv, pingTime
}
//return Success packetRecv averagePingTime specificIPAddr
func tcpingHandler(ip net.IPAddr, pingCount int, progressHandler func(e progressEvent)) (bool, int, float64, net.IPAddr) {
ipCanConnect := false
pingRecv := 0
pingTime := 0.0
for !ipCanConnect {
pingRecvCurrent, pingTimeCurrent := checkConnection(ip)
if pingRecvCurrent != 0 {
ipCanConnect = true
pingRecv = pingRecvCurrent
pingTime = pingTimeCurrent
} else {
ip.IP[15]++
if ip.IP[15] == 0 {
break
}
break
}
}
if ipCanConnect {
progressHandler(AvailableIPFound)
for i := failTime; i < pingCount; i++ {
pingSuccess, pingTimeCurrent := tcping(ip)
progressHandler(NormalPing)
if pingSuccess {
pingRecv++
pingTime += pingTimeCurrent
}
}
return true, pingRecv, pingTime / float64(pingRecv), ip
} else {
progressHandler(NoAvailableIPFound)
return false, 0, 0, net.IPAddr{}
}
}
func tcpingGoroutine(wg *sync.WaitGroup, mutex *sync.Mutex, ip net.IPAddr, pingCount int, csv *[][]string, control chan bool, progressHandler func(e progressEvent)) {
defer wg.Done()
success, pingRecv, pingTimeAvg, currentIP := tcpingHandler(ip, pingCount, progressHandler)
if success {
mutex.Lock()
*csv = append(*csv, []string{currentIP.String(), strconv.Itoa(pingRecv), strconv.FormatFloat(pingTimeAvg, 'f', 4, 64)})
mutex.Unlock()
}
<-control
}