Golang implementation of the Reliable UDP transport, revised from an original documented mostly in chinese.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

listener.go 1.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package rudp
  2. import (
  3. "net"
  4. "sync"
  5. )
  6. func NewListener(conn *net.UDPConn) *RudpListener {
  7. listen := &RudpListener{conn: conn,
  8. newRudpConn: make(chan *RudpConn, 1024),
  9. newRudpErr: make(chan error, 12),
  10. rudpConnMap: make(map[string]*RudpConn)}
  11. go listen.run()
  12. return listen
  13. }
  14. type RudpListener struct {
  15. conn *net.UDPConn
  16. lock sync.RWMutex
  17. newRudpConn chan *RudpConn
  18. newRudpErr chan error
  19. rudpConnMap map[string]*RudpConn
  20. }
  21. //net listener interface
  22. func (rl *RudpListener) Accept() (net.Conn, error) { return rl.AcceptRudp() }
  23. func (rl *RudpListener) Close() error {
  24. rl.CloseAllRudp()
  25. return rl.conn.Close()
  26. }
  27. func (rl *RudpListener) Addr() net.Addr { return rl.conn.LocalAddr() }
  28. func (rl *RudpListener) CloseRudp(addr string) {
  29. rl.lock.Lock()
  30. delete(rl.rudpConnMap, addr)
  31. rl.lock.Unlock()
  32. }
  33. func (rl *RudpListener) CloseAllRudp() {
  34. rl.lock.Lock()
  35. for _, rconn := range rl.rudpConnMap {
  36. rconn.closef = nil
  37. rconn.Close()
  38. }
  39. rl.lock.Unlock()
  40. }
  41. func (rl *RudpListener) AcceptRudp() (*RudpConn, error) {
  42. select {
  43. case c := <-rl.newRudpConn:
  44. return c, nil
  45. case e := <-rl.newRudpErr:
  46. return nil, e
  47. }
  48. }
  49. func (rl *RudpListener) run() {
  50. data := make([]byte, MAX_PACKAGE)
  51. for {
  52. n, remoteAddr, err := rl.conn.ReadFromUDP(data)
  53. if err != nil {
  54. rl.CloseAllRudp()
  55. rl.newRudpErr <- err
  56. return
  57. }
  58. rl.lock.RLock()
  59. rudpConn, ok := rl.rudpConnMap[remoteAddr.String()]
  60. rl.lock.RUnlock()
  61. if !ok {
  62. rudpConn = NewUnConn(rl.conn, remoteAddr, New(), rl.CloseRudp)
  63. rl.lock.Lock()
  64. rl.rudpConnMap[remoteAddr.String()] = rudpConn
  65. rl.lock.Unlock()
  66. rl.newRudpConn <- rudpConn
  67. }
  68. bts := make([]byte, n)
  69. dataRead := data[:n]
  70. copy(bts, dataRead)
  71. rudpConn.in <- bts
  72. }
  73. }