csv.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package utils
  2. import (
  3. "encoding/csv"
  4. "log"
  5. "net"
  6. "os"
  7. "sort"
  8. "strconv"
  9. "time"
  10. )
  11. var (
  12. MaxDelay = 9999 * time.Millisecond
  13. MinDelay = time.Duration(0)
  14. InputMaxDelay = MaxDelay
  15. InputMinDelay = MinDelay
  16. )
  17. type PingData struct {
  18. IP net.IPAddr
  19. Sended int
  20. Received int
  21. Delay time.Duration
  22. }
  23. type CloudflareIPData struct {
  24. *PingData
  25. recvRate float32
  26. downloadSpeed float32
  27. }
  28. func (cf *CloudflareIPData) getRecvRate() float32 {
  29. if cf.recvRate == 0 {
  30. pingLost := cf.Sended - cf.Received
  31. cf.recvRate = float32(pingLost) / float32(cf.Sended)
  32. }
  33. return cf.recvRate
  34. }
  35. func (cf *CloudflareIPData) toString() []string {
  36. result := make([]string, 6)
  37. result[0] = cf.IP.String()
  38. result[1] = strconv.Itoa(cf.Sended)
  39. result[2] = strconv.Itoa(cf.Received)
  40. result[3] = strconv.FormatFloat(float64(cf.getRecvRate()), 'f', 2, 32)
  41. result[4] = cf.Delay.String()
  42. result[5] = strconv.FormatFloat(float64(cf.downloadSpeed)/1024/1024, 'f', 2, 32)
  43. return result
  44. }
  45. func ExportCsv(filePath string, data []CloudflareIPData) {
  46. fp, err := os.Create(filePath)
  47. if err != nil {
  48. log.Fatalf("创建文件[%s]失败:%v", filePath, err)
  49. return
  50. }
  51. defer fp.Close()
  52. w := csv.NewWriter(fp) //创建一个新的写入文件流
  53. w.Write([]string{"IP 地址", "已发送", "已接收", "丢包率", "平均延迟", "下载速度 (MB/s)"})
  54. w.WriteAll(convertToString(data))
  55. w.Flush()
  56. }
  57. func convertToString(data []CloudflareIPData) [][]string {
  58. result := make([][]string, 0)
  59. for _, v := range data {
  60. result = append(result, v.toString())
  61. }
  62. return result
  63. }
  64. type PingDelaySet []CloudflareIPData
  65. func (s PingDelaySet) FilterDelay() (data PingDelaySet) {
  66. sort.Sort(s)
  67. if InputMaxDelay >= MaxDelay || InputMinDelay <= MinDelay {
  68. return s
  69. }
  70. for _, v := range s {
  71. if v.Delay > MaxDelay { // 平均延迟上限
  72. break
  73. }
  74. if v.Delay <= MinDelay { // 平均延迟下限
  75. continue
  76. }
  77. data = append(data, v) // 延迟满足条件时,添加到新数组中
  78. }
  79. return
  80. }
  81. func (s PingDelaySet) Len() int {
  82. return len(s)
  83. }
  84. func (s PingDelaySet) Less(i, j int) bool {
  85. iRate, jRate := s[i].getRecvRate(), s[j].getRecvRate()
  86. if iRate != jRate {
  87. return iRate < jRate
  88. }
  89. return s[i].Delay < s[j].Delay
  90. }
  91. func (s PingDelaySet) Swap(i, j int) {
  92. s[i], s[j] = s[j], s[i]
  93. }
  94. // 下载速度排序
  95. type DownloadSpeedSet []CloudflareIPData
  96. func (s DownloadSpeedSet) Len() int {
  97. return len(s)
  98. }
  99. func (s DownloadSpeedSet) Less(i, j int) bool {
  100. return s[i].downloadSpeed > s[j].downloadSpeed
  101. }
  102. func (s DownloadSpeedSet) Swap(i, j int) {
  103. s[i], s[j] = s[j], s[i]
  104. }