tcping.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package task
  2. import (
  3. "fmt"
  4. "net"
  5. "sort"
  6. "strconv"
  7. "sync"
  8. "time"
  9. "github.com/XIU2/CloudflareSpeedTest/utils"
  10. )
  11. const (
  12. tcpConnectTimeout = time.Second * 1
  13. maxRoutine = 1000
  14. defaultRoutines = 200
  15. defaultPort = 443
  16. defaultPingTimes = 4
  17. )
  18. var (
  19. Routines = defaultRoutines
  20. TCPPort int = defaultPort
  21. PingTimes int = defaultPingTimes
  22. )
  23. type Ping struct {
  24. wg *sync.WaitGroup
  25. m *sync.Mutex
  26. ips []*net.IPAddr
  27. csv utils.PingDelaySet
  28. control chan bool
  29. bar *utils.Bar
  30. }
  31. func checkPingDefault() {
  32. if Routines <= 0 {
  33. Routines = defaultRoutines
  34. }
  35. if TCPPort <= 0 || TCPPort >= 65535 {
  36. TCPPort = defaultPort
  37. }
  38. if PingTimes <= 0 {
  39. PingTimes = defaultPingTimes
  40. }
  41. }
  42. func NewPing() *Ping {
  43. checkPingDefault()
  44. ips := loadIPRanges()
  45. return &Ping{
  46. wg: &sync.WaitGroup{},
  47. m: &sync.Mutex{},
  48. ips: ips,
  49. csv: make(utils.PingDelaySet, 0),
  50. control: make(chan bool, Routines),
  51. bar: utils.NewBar(len(ips), "可用:", ""),
  52. }
  53. }
  54. func (p *Ping) Run() utils.PingDelaySet {
  55. if len(p.ips) == 0 {
  56. return p.csv
  57. }
  58. if Httping {
  59. fmt.Printf("\033[34m开始延迟测速(模式:HTTP, 端口:%d, 范围:%v ~ %v ms, 丢包:%.2f)\033[0m\n", TCPPort, utils.InputMinDelay.Milliseconds(), utils.InputMaxDelay.Milliseconds(), utils.InputMaxLossRate)
  60. } else {
  61. fmt.Printf("\033[34m开始延迟测速(模式:TCP, 端口:%d, 范围:%v ~ %v ms, 丢包:%.2f)\033[0m\n", TCPPort, utils.InputMinDelay.Milliseconds(), utils.InputMaxDelay.Milliseconds(), utils.InputMaxLossRate)
  62. }
  63. for _, ip := range p.ips {
  64. p.wg.Add(1)
  65. p.control <- false
  66. go p.start(ip)
  67. }
  68. p.wg.Wait()
  69. p.bar.Done()
  70. sort.Sort(p.csv)
  71. return p.csv
  72. }
  73. func (p *Ping) start(ip *net.IPAddr) {
  74. defer p.wg.Done()
  75. p.tcpingHandler(ip)
  76. <-p.control
  77. }
  78. // bool connectionSucceed float32 time
  79. func (p *Ping) tcping(ip *net.IPAddr) (bool, time.Duration) {
  80. startTime := time.Now()
  81. var fullAddress string
  82. if isIPv4(ip.String()) {
  83. fullAddress = fmt.Sprintf("%s:%d", ip.String(), TCPPort)
  84. } else {
  85. fullAddress = fmt.Sprintf("[%s]:%d", ip.String(), TCPPort)
  86. }
  87. conn, err := net.DialTimeout("tcp", fullAddress, tcpConnectTimeout)
  88. if err != nil {
  89. return false, 0
  90. }
  91. defer conn.Close()
  92. duration := time.Since(startTime)
  93. return true, duration
  94. }
  95. // pingReceived pingTotalTime
  96. func (p *Ping) checkConnection(ip *net.IPAddr) (recv int, totalDelay time.Duration, colo string) {
  97. if Httping {
  98. recv, totalDelay, colo = p.httping(ip)
  99. return
  100. }
  101. colo = "" // TCPing 不获取 colo
  102. for i := 0; i < PingTimes; i++ {
  103. if ok, delay := p.tcping(ip); ok {
  104. recv++
  105. totalDelay += delay
  106. }
  107. }
  108. return
  109. }
  110. func (p *Ping) appendIPData(data *utils.PingData) {
  111. p.m.Lock()
  112. defer p.m.Unlock()
  113. p.csv = append(p.csv, utils.CloudflareIPData{
  114. PingData: data,
  115. })
  116. }
  117. // handle tcping
  118. func (p *Ping) tcpingHandler(ip *net.IPAddr) {
  119. recv, totalDlay, colo := p.checkConnection(ip)
  120. nowAble := len(p.csv)
  121. if recv != 0 {
  122. nowAble++
  123. }
  124. p.bar.Grow(1, strconv.Itoa(nowAble))
  125. if recv == 0 {
  126. return
  127. }
  128. data := &utils.PingData{
  129. IP: ip,
  130. Sended: PingTimes,
  131. Received: recv,
  132. Delay: totalDlay / time.Duration(recv),
  133. Colo: colo,
  134. }
  135. p.appendIPData(data)
  136. }