rebuild tcping
This commit is contained in:
parent
83c63e975e
commit
71671ebe66
|
@ -1,2 +1,4 @@
|
||||||
dist
|
dist
|
||||||
Releases
|
Releases
|
||||||
|
*.exe
|
||||||
|
*.csv
|
||||||
|
|
4
main.go
4
main.go
|
@ -158,7 +158,7 @@ func main() {
|
||||||
control := make(chan bool, pingRoutine)
|
control := make(chan bool, pingRoutine)
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
control <- false
|
// control <- false
|
||||||
handleProgress := handleProgressGenerator(bar) // 多线程进度条
|
handleProgress := handleProgressGenerator(bar) // 多线程进度条
|
||||||
go tcpingGoroutine(&wg, &mu, ip, tcpPort, pingTime, &data, control, handleProgress)
|
go tcpingGoroutine(&wg, &mu, ip, tcpPort, pingTime, &data, control, handleProgress)
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ func printResult(data []CloudflareIPData) {
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%-16s%-5s%-5s%-5s%-6s%-11s\n", resHeader...)
|
fmt.Printf("%-16s%-5s%-5s%-5s%-6s%-11s\n", resHeader...)
|
||||||
for i := 0; i < printResultNum; i++ {
|
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])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ func tcpingHandler(ip net.IPAddr, tcpPort, pingCount int, progressHandler func(e
|
||||||
}
|
}
|
||||||
progressHandler(AvailableIPFound)
|
progressHandler(AvailableIPFound)
|
||||||
for i := failTime; i < pingCount; i++ {
|
for i := failTime; i < pingCount; i++ {
|
||||||
|
fmt.Println("failTime", failTime)
|
||||||
pingSuccess, pingTimeCurrent := tcping(ip, tcpPort)
|
pingSuccess, pingTimeCurrent := tcping(ip, tcpPort)
|
||||||
progressHandler(NormalPing)
|
progressHandler(NormalPing)
|
||||||
if pingSuccess {
|
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)) {
|
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()
|
defer wg.Done()
|
||||||
|
// fmt.Println(ip.String())
|
||||||
success, pingRecv, pingTimeAvg, currentIP := tcpingHandler(ip, tcpPort, pingCount, progressHandler)
|
success, pingRecv, pingTimeAvg, currentIP := tcpingHandler(ip, tcpPort, pingCount, progressHandler)
|
||||||
if success {
|
if success {
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
|
@ -89,7 +91,7 @@ func tcpingGoroutine(wg *sync.WaitGroup, mutex *sync.Mutex, ip net.IPAddr, tcpPo
|
||||||
*csv = append(*csv, cfdata)
|
*csv = append(*csv, cfdata)
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
}
|
}
|
||||||
<-control
|
// <-control
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDialContextByAddr(fakeSourceAddr string) func(ctx context.Context, network, address string) (net.Conn, error) {
|
func GetDialContextByAddr(fakeSourceAddr string) func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
|
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
|
||||||
}
|
|
24
utils/csv.go
24
utils/csv.go
|
@ -9,19 +9,23 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PingData struct {
|
||||||
|
IP net.IPAddr
|
||||||
|
Count int
|
||||||
|
Received int
|
||||||
|
Delay time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
type CloudflareIPData struct {
|
type CloudflareIPData struct {
|
||||||
ip net.IPAddr
|
*PingData
|
||||||
pingCount int
|
|
||||||
pingReceived int
|
|
||||||
recvRate float32
|
recvRate float32
|
||||||
downloadSpeed float32
|
downloadSpeed float32
|
||||||
pingTime time.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cf *CloudflareIPData) getRecvRate() float32 {
|
func (cf *CloudflareIPData) getRecvRate() float32 {
|
||||||
if cf.recvRate == 0 {
|
if cf.recvRate == 0 {
|
||||||
pingLost := cf.pingCount - cf.pingReceived
|
pingLost := cf.Count - cf.Received
|
||||||
cf.recvRate = float32(pingLost) / float32(cf.pingCount)
|
cf.recvRate = float32(pingLost) / float32(cf.Count)
|
||||||
}
|
}
|
||||||
return cf.recvRate
|
return cf.recvRate
|
||||||
}
|
}
|
||||||
|
@ -41,11 +45,11 @@ func ExportCsv(filePath string, data []CloudflareIPData) {
|
||||||
|
|
||||||
func (cf *CloudflareIPData) toString() []string {
|
func (cf *CloudflareIPData) toString() []string {
|
||||||
result := make([]string, 6)
|
result := make([]string, 6)
|
||||||
result[0] = cf.ip.String()
|
result[0] = cf.IP.String()
|
||||||
result[1] = strconv.Itoa(cf.pingCount)
|
result[1] = strconv.Itoa(cf.Count)
|
||||||
result[2] = strconv.Itoa(cf.pingReceived)
|
result[2] = strconv.Itoa(cf.Received)
|
||||||
result[3] = strconv.FormatFloat(float64(cf.getRecvRate()), 'f', 2, 32)
|
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)
|
result[5] = strconv.FormatFloat(float64(cf.downloadSpeed)/1024/1024, 'f', 2, 32)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
|
import "github.com/cheggaaa/pb/v3"
|
||||||
|
|
||||||
type ProgressEvent int
|
type ProgressEvent int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -7,3 +9,24 @@ const (
|
||||||
AvailableIPFound
|
AvailableIPFound
|
||||||
NormalPing
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue