浏览代码

rebuild tcping

mz 3 年之前
父节点
当前提交
71671ebe66
共有 7 个文件被更改,包括 173 次插入32 次删除
  1. 2 0
      .gitignore
  2. 2 2
      main.go
  3. 3 1
      tcping.go
  4. 129 0
      tcping/ping.go
  5. 0 19
      tcping/tcping.go
  6. 14 10
      utils/csv.go
  7. 23 0
      utils/progress.go

+ 2 - 0
.gitignore

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

+ 2 - 2
main.go

@@ -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])
 		}
 	}
 

+ 3 - 1
tcping.go

@@ -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 - 0
tcping/ping.go

@@ -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),
+	}
+}

+ 0 - 19
tcping/tcping.go

@@ -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)
-}

+ 14 - 10
utils/csv.go

@@ -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
 }

+ 23 - 0
utils/progress.go

@@ -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()
+		}
+	}
+}