portmanager.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package gb28181
  2. import (
  3. "io"
  4. "fmt"
  5. "net"
  6. "sync"
  7. )
  8. type PortManager struct {
  9. recycle chan uint16
  10. max uint16
  11. pos uint16
  12. Valid bool
  13. }
  14. var portMutex sync.Mutex
  15. func (pm *PortManager) Init(start, end uint16) {
  16. pm.pos = start - 1
  17. pm.max = end
  18. if pm.pos > 0 && pm.max > pm.pos {
  19. pm.Valid = true
  20. pm.recycle = make(chan uint16, pm.Range())
  21. }
  22. }
  23. func (pm *PortManager) Range() uint16 {
  24. return pm.max - pm.pos
  25. }
  26. func (pm *PortManager) Recycle(p uint16) (err error) {
  27. select {
  28. case pm.recycle <- p:
  29. //fmt.Println("recycle port 00000000000000000000000000",p)
  30. return nil
  31. default:
  32. return io.EOF //TODO: 换一个Error
  33. }
  34. }
  35. func tryTcpPortUnUse(port uint16) bool {
  36. ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
  37. if err != nil {
  38. // 如果监听失败,则说明端口已被占用
  39. fmt.Printf("Port %d is NOT available,err=%s\n", port,err.Error())
  40. return false
  41. }
  42. defer ln.Close()
  43. //fmt.Println("端口可用 ------------------------",port)
  44. return true
  45. }
  46. func (pm *PortManager) GetUnUseTcpPort() (p uint16, err error){
  47. for i:=0;i<3;i++{
  48. p, err = pm.GetPort()
  49. if err != nil {
  50. return
  51. }
  52. if tryTcpPortUnUse(p){
  53. return
  54. }
  55. }
  56. return 0 ,fmt.Errorf("尝试三次端口被占用")
  57. }
  58. func (pm *PortManager) GetPort() (p uint16, err error) {
  59. portMutex.Lock()
  60. defer portMutex.Unlock()
  61. select {
  62. case p = <-pm.recycle:
  63. return
  64. default:
  65. if pm.Range() > 0 {
  66. pm.pos++
  67. p = pm.pos
  68. return
  69. } else {
  70. return 0 , fmt.Errorf("无可用端口")
  71. //return 0, io.EOF //TODO: 换一个Error
  72. }
  73. }
  74. }