udp.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package commonutil
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "net"
  6. "time"
  7. )
  8. //
  9. type UdpClient struct {
  10. Local string
  11. Connect *net.UDPConn
  12. BufSize int
  13. }
  14. //指令
  15. const (
  16. OP_NOOP = byte(iota)
  17. OP_JOIN
  18. OP_BYE
  19. OP_SAY_ONLINE
  20. OP_TYPE_DATA
  21. OP_GET_DOWNLOADERCODE //上报下载器代码
  22. OP_WILLCHANGEIP //将要切换IP
  23. OP_PUSH_DOWNLOADERCODES //
  24. OP_DELETE_DOWNLOADERCODES //需要删除
  25. OP_NEWCLIENT //下载器重新链接
  26. )
  27. //
  28. func (c *UdpClient) Listen(fn func(byte, []byte, *net.UDPAddr)) {
  29. listenAddr, _ := net.ResolveUDPAddr("udp4", c.Local)
  30. c.Connect, _ = net.ListenUDP("udp4", listenAddr)
  31. go c.readUdp(fn)
  32. }
  33. //写
  34. func (c *UdpClient) WriteUdp(data []byte /*写入数据*/, act byte /*动作*/, toaddr *net.UDPAddr /*目标端地址*/) error {
  35. bs := make([]byte, 1)
  36. bs[0] = act
  37. sizebs := Int2Byte(int32(len(data)))
  38. bs = append(bs, sizebs...)
  39. bs = append(bs, data...)
  40. if len(bs) > c.BufSize {
  41. bs = bs[:c.BufSize]
  42. } else if len(bs) < c.BufSize {
  43. bs = append(bs, bytes.Repeat([]byte{0}, c.BufSize-len(bs))...)
  44. }
  45. for i := 0; i < 5; i++ { //尝试5次
  46. _, err := c.Connect.WriteToUDP(bs, toaddr)
  47. if err == nil {
  48. break
  49. }
  50. time.Sleep(1 * time.Second)
  51. }
  52. return nil
  53. }
  54. //读
  55. func (c *UdpClient) readUdp(fn func(byte, []byte, *net.UDPAddr)) {
  56. for {
  57. head := make([]byte, c.BufSize)
  58. n, ra, err := c.Connect.ReadFromUDP(head)
  59. if err != nil || n == 0 { //取不到数据
  60. time.Sleep(1 * time.Second)
  61. continue
  62. }
  63. size := int(Byte2Int(head[1:5]))
  64. if size < 1 { //无数据,仅仅是控制指令
  65. go fn(head[0], []byte{}, ra)
  66. } else {
  67. if size > c.BufSize-5 {
  68. size = c.BufSize - 5
  69. }
  70. go fn(head[0], head[5:5+size], ra)
  71. }
  72. }
  73. }
  74. //
  75. func Byte2Int(src []byte) int32 {
  76. var ret int32
  77. binary.Read(bytes.NewReader(src), binary.BigEndian, &ret)
  78. return ret
  79. }
  80. //
  81. func Int2Byte(src int32) []byte {
  82. buf := bytes.NewBuffer([]byte{})
  83. binary.Write(buf, binary.BigEndian, src)
  84. return buf.Bytes()
  85. }