functions.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package proxy
  2. import (
  3. "io"
  4. "net"
  5. "runtime/debug"
  6. "sync"
  7. "time"
  8. )
  9. func ConnectHost(hostAndPort string, timeout int) (conn net.Conn, err error) {
  10. conn, err = net.DialTimeout("tcp", hostAndPort, time.Duration(timeout)*time.Millisecond)
  11. return
  12. }
  13. func CloseConn(conn net.Conn) {
  14. if conn != nil {
  15. _ = conn.SetDeadline(time.Now().Add(time.Millisecond))
  16. _ = conn.Close()
  17. }
  18. }
  19. func IoBind(dst io.ReadWriter, src io.ReadWriter, fn func(isSrcErr bool, err error), cfn func(count int, isPositive bool), bytesPreSec float64) {
  20. var one = &sync.Once{}
  21. go func() {
  22. defer func() {
  23. if e := recover(); e != nil {
  24. logger.Sugar().Errorf("IoBind crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
  25. }
  26. }()
  27. var err error
  28. var isSrcErr bool
  29. if bytesPreSec > 0 {
  30. newReader := NewReader(src)
  31. newReader.SetRateLimit(bytesPreSec)
  32. _, isSrcErr, err = IoCopy(dst, newReader, func(c int) {
  33. cfn(c, false)
  34. })
  35. } else {
  36. _, isSrcErr, err = IoCopy(dst, src, func(c int) {
  37. cfn(c, false)
  38. })
  39. }
  40. if err != nil {
  41. one.Do(func() {
  42. fn(isSrcErr, err)
  43. })
  44. }
  45. }()
  46. go func() {
  47. defer func() {
  48. if e := recover(); e != nil {
  49. logger.Sugar().Errorf("IoBind crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
  50. }
  51. }()
  52. var err error
  53. var isSrcErr bool
  54. if bytesPreSec > 0 {
  55. newReader := NewReader(dst)
  56. newReader.SetRateLimit(bytesPreSec)
  57. _, isSrcErr, err = IoCopy(src, newReader, func(c int) {
  58. cfn(c, true)
  59. })
  60. } else {
  61. _, isSrcErr, err = IoCopy(src, dst, func(c int) {
  62. cfn(c, true)
  63. })
  64. }
  65. if err != nil {
  66. one.Do(func() {
  67. fn(isSrcErr, err)
  68. })
  69. }
  70. }()
  71. }
  72. func IoCopy(dst io.Writer, src io.Reader, fn ...func(count int)) (written int64, isSrcErr bool, err error) {
  73. buf := make([]byte, 32*1024)
  74. for {
  75. nr, er := src.Read(buf)
  76. if nr > 0 {
  77. nw, ew := dst.Write(buf[0:nr])
  78. if nw > 0 {
  79. written += int64(nw)
  80. if len(fn) == 1 {
  81. fn[0](nw)
  82. }
  83. }
  84. if ew != nil {
  85. err = ew
  86. break
  87. }
  88. if nr != nw {
  89. err = io.ErrShortWrite
  90. break
  91. }
  92. }
  93. if er != nil {
  94. err = er
  95. isSrcErr = true
  96. break
  97. }
  98. }
  99. return written, isSrcErr, err
  100. }