udp.go 1.6 KB

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