rebuild tcping

This commit is contained in:
mz 2021-11-09 23:39:42 +08:00
parent 83c63e975e
commit 71671ebe66
7 changed files with 173 additions and 32 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
dist
Releases
*.exe
*.csv

View File

@ -158,7 +158,7 @@ func main() {
control := make(chan bool, pingRoutine)
for _, ip := range ips {
wg.Add(1)
control <- false
// control <- false
handleProgress := handleProgressGenerator(bar) // 多线程进度条
go tcpingGoroutine(&wg, &mu, ip, tcpPort, pingTime, &data, control, handleProgress)
}
@ -253,7 +253,7 @@ func printResult(data []CloudflareIPData) {
} else {
fmt.Printf("%-16s%-5s%-5s%-5s%-6s%-11s\n", resHeader...)
for i := 0; i < printResultNum; i++ {
fmt.Printf("%-18s%-8s%-8s%-8s%-10s%-15s\n", ipPadding(dateString[i][0]), dateString[i][1], dateString[i][2], dateString[i][3], dateString[i][4], dateString[i][5])
fmt.Printf("%-18s%-8s%-8s%-8s%-15s%-15s\n", ipPadding(dateString[i][0]), dateString[i][1], dateString[i][2], dateString[i][3], dateString[i][4], dateString[i][5])
}
}

View File

@ -66,6 +66,7 @@ func tcpingHandler(ip net.IPAddr, tcpPort, pingCount int, progressHandler func(e
}
progressHandler(AvailableIPFound)
for i := failTime; i < pingCount; i++ {
fmt.Println("failTime", failTime)
pingSuccess, pingTimeCurrent := tcping(ip, tcpPort)
progressHandler(NormalPing)
if pingSuccess {
@ -78,6 +79,7 @@ func tcpingHandler(ip net.IPAddr, tcpPort, pingCount int, progressHandler func(e
func tcpingGoroutine(wg *sync.WaitGroup, mutex *sync.Mutex, ip net.IPAddr, tcpPort int, pingCount int, csv *[]CloudflareIPData, control chan bool, progressHandler func(e progressEvent)) {
defer wg.Done()
// fmt.Println(ip.String())
success, pingRecv, pingTimeAvg, currentIP := tcpingHandler(ip, tcpPort, pingCount, progressHandler)
if success {
mutex.Lock()
@ -89,7 +91,7 @@ func tcpingGoroutine(wg *sync.WaitGroup, mutex *sync.Mutex, ip net.IPAddr, tcpPo
*csv = append(*csv, cfdata)
mutex.Unlock()
}
<-control
// <-control
}
func GetDialContextByAddr(fakeSourceAddr string) func(ctx context.Context, network, address string) (net.Conn, error) {

129
tcping/ping.go Normal file
View File

@ -0,0 +1,129 @@
package tcp
import (
"fmt"
"net"
"sync"
"time"
"CloudflareSpeedTest/utils"
)
const tcpConnectTimeout = time.Second * 1
type Ping struct {
wg *sync.WaitGroup
m *sync.Mutex
ips []net.IPAddr
isIPv6 bool
tcpPort int
pingCount int
csv []utils.CloudflareIPData
control chan bool
progressHandler func(e utils.ProgressEvent)
}
func NewPing(ips []net.IPAddr, port, pingTime int, ipv6 bool) *Ping {
return &Ping{
wg: &sync.WaitGroup{},
m: &sync.Mutex{},
ips: ips,
isIPv6: ipv6,
tcpPort: port,
pingCount: pingTime,
csv: make([]utils.CloudflareIPData, 0),
control: make(chan bool),
}
}
func (p *Ping) Run() {
for _, ip := range p.ips {
p.wg.Add(1)
p.control <- false
go p.start(ip)
}
}
func (p *Ping) start(ip net.IPAddr) {
defer p.wg.Done()
if ok, data := p.tcpingHandler(ip, nil); ok {
p.appendIPData(data)
}
<-p.control
}
func (p *Ping) appendIPData(data *utils.PingData) {
p.m.Lock()
defer p.m.Unlock()
p.csv = append(p.csv, utils.CloudflareIPData{
PingData: data,
})
}
//bool connectionSucceed float32 time
func (p *Ping) tcping(ip net.IPAddr) (bool, time.Duration) {
startTime := time.Now()
fullAddress := fmt.Sprintf("%s:%d", ip.String(), p.tcpPort)
//fmt.Println(ip.String())
if p.isIPv6 { // IPv6 需要加上 []
fullAddress = fmt.Sprintf("[%s]:%d", ip.String(), p.tcpPort)
}
conn, err := net.DialTimeout("tcp", fullAddress, tcpConnectTimeout)
if err != nil {
return false, 0
}
defer conn.Close()
duration := time.Since(startTime)
return true, duration
}
//pingReceived pingTotalTime
func (p *Ping) checkConnection(ip net.IPAddr) (pingRecv int, pingTime time.Duration) {
for i := 0; i < p.pingCount; i++ {
if pingSucceed, pingTimeCurrent := p.tcping(ip); pingSucceed {
pingRecv++
pingTime += pingTimeCurrent
}
}
return
}
//return Success packetRecv averagePingTime specificIPAddr
func (p *Ping) tcpingHandler(ip net.IPAddr, progressHandler func(e utils.ProgressEvent)) (bool, *utils.PingData) {
ipCanConnect := false
pingRecv := 0
var pingTime time.Duration
for !ipCanConnect {
pingRecvCurrent, pingTimeCurrent := p.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(utils.NoAvailableIPFound)
return false, nil
}
progressHandler(utils.AvailableIPFound)
for i := 0; i < p.pingCount; i++ {
pingSuccess, pingTimeCurrent := p.tcping(ip)
progressHandler(utils.NormalPing)
if pingSuccess {
pingRecv++
pingTime += pingTimeCurrent
}
}
return true, &utils.PingData{
IP: ip,
Count: p.pingCount,
Received: pingRecv,
Delay: pingTime / time.Duration(pingRecv),
}
}

View File

@ -1,19 +0,0 @@
package tcping
import (
"net"
"sync"
"CloudflareSpeedTest/utils"
)
type Tcp struct {
wg *sync.WaitGroup
mutex *sync.Mutex
ip net.IPAddr
tcpPort int
pingCount int
csv *[]utils.CloudflareIPData
control chan bool
progressHandler func(e utils.ProgressEvent)
}

View File

@ -9,19 +9,23 @@ import (
"time"
)
type PingData struct {
IP net.IPAddr
Count int
Received int
Delay time.Duration
}
type CloudflareIPData struct {
ip net.IPAddr
pingCount int
pingReceived int
*PingData
recvRate float32
downloadSpeed float32
pingTime time.Duration
}
func (cf *CloudflareIPData) getRecvRate() float32 {
if cf.recvRate == 0 {
pingLost := cf.pingCount - cf.pingReceived
cf.recvRate = float32(pingLost) / float32(cf.pingCount)
pingLost := cf.Count - cf.Received
cf.recvRate = float32(pingLost) / float32(cf.Count)
}
return cf.recvRate
}
@ -41,11 +45,11 @@ func ExportCsv(filePath string, data []CloudflareIPData) {
func (cf *CloudflareIPData) toString() []string {
result := make([]string, 6)
result[0] = cf.ip.String()
result[1] = strconv.Itoa(cf.pingCount)
result[2] = strconv.Itoa(cf.pingReceived)
result[0] = cf.IP.String()
result[1] = strconv.Itoa(cf.Count)
result[2] = strconv.Itoa(cf.Received)
result[3] = strconv.FormatFloat(float64(cf.getRecvRate()), 'f', 2, 32)
result[4] = cf.pingTime.String()
result[4] = cf.Delay.String()
result[5] = strconv.FormatFloat(float64(cf.downloadSpeed)/1024/1024, 'f', 2, 32)
return result
}

View File

@ -1,5 +1,7 @@
package utils
import "github.com/cheggaaa/pb/v3"
type ProgressEvent int
const (
@ -7,3 +9,24 @@ const (
AvailableIPFound
NormalPing
)
type Bar struct {
*pb.ProgressBar
}
func NewBar(count int) *Bar {
return &Bar{pb.Simple.Start(count)}
}
func handleProgressGenerator(pb *pb.ProgressBar) func(e ProgressEvent) {
return func(e ProgressEvent) {
switch e {
case NoAvailableIPFound:
// pb.Add(pingTime)
case AvailableIPFound:
// pb.Add(failTime)
case NormalPing:
pb.Increment()
}
}
}