tcping.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package main
  2. import (
  3. "net"
  4. "strconv"
  5. "sync"
  6. "time"
  7. )
  8. const defaultTcpPort = 443
  9. const tcpConnectTimeout = time.Second * 1
  10. const failTime = 4
  11. //bool connectionSucceed float64 time
  12. func tcping(ip net.IPAddr) (bool, float64) {
  13. startTime := time.Now()
  14. conn, err := net.DialTimeout("tcp", ip.String()+":"+strconv.Itoa(defaultTcpPort), tcpConnectTimeout)
  15. if err != nil {
  16. return false, 0
  17. } else {
  18. var endTime = time.Since(startTime)
  19. var duration = float64(endTime.Microseconds()) / 1000.0
  20. _ = conn.Close()
  21. return true, duration
  22. }
  23. }
  24. //pingReceived pingTotalTime
  25. func checkConnection(ip net.IPAddr) (int, float64) {
  26. pingRecv := 0
  27. pingTime := 0.0
  28. for i := 1; i <= failTime; i++ {
  29. pingSucceed, pingTimeCurrent := tcping(ip)
  30. if pingSucceed {
  31. pingRecv++
  32. pingTime += pingTimeCurrent
  33. }
  34. }
  35. return pingRecv, pingTime
  36. }
  37. //return Success packetRecv averagePingTime specificIPAddr
  38. func tcpingHandler(ip net.IPAddr, pingCount int, progressHandler func(e progressEvent)) (bool, int, float64, net.IPAddr) {
  39. ipCanConnect := false
  40. pingRecv := 0
  41. pingTime := 0.0
  42. for !ipCanConnect {
  43. pingRecvCurrent, pingTimeCurrent := checkConnection(ip)
  44. if pingRecvCurrent != 0 {
  45. ipCanConnect = true
  46. pingRecv = pingRecvCurrent
  47. pingTime = pingTimeCurrent
  48. } else {
  49. ip.IP[15]++
  50. if ip.IP[15] == 0 {
  51. break
  52. }
  53. break
  54. }
  55. }
  56. if ipCanConnect {
  57. progressHandler(AvailableIPFound)
  58. for i := failTime; i < pingCount; i++ {
  59. pingSuccess, pingTimeCurrent := tcping(ip)
  60. progressHandler(NormalPing)
  61. if pingSuccess {
  62. pingRecv++
  63. pingTime += pingTimeCurrent
  64. }
  65. }
  66. return true, pingRecv, pingTime / float64(pingRecv), ip
  67. } else {
  68. progressHandler(NoAvailableIPFound)
  69. return false, 0, 0, net.IPAddr{}
  70. }
  71. }
  72. func tcpingGoroutine(wg *sync.WaitGroup, mutex *sync.Mutex, ip net.IPAddr, pingCount int, csv *[][]string, control chan bool, progressHandler func(e progressEvent)) {
  73. defer wg.Done()
  74. success, pingRecv, pingTimeAvg, currentIP := tcpingHandler(ip, pingCount, progressHandler)
  75. if success {
  76. mutex.Lock()
  77. *csv = append(*csv, []string{currentIP.String(), strconv.Itoa(pingRecv), strconv.FormatFloat(pingTimeAvg, 'f', 4, 64)})
  78. mutex.Unlock()
  79. }
  80. <-control
  81. }