tcp_reader.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package uhf
  2. import (
  3. "errors"
  4. "net"
  5. "time"
  6. )
  7. type TCPReader struct {
  8. IP string
  9. Port int
  10. conn net.Conn
  11. isConnected bool
  12. buffer []byte // 内部拼包缓冲区(关键修复)
  13. }
  14. // 实现 Reader 接口的继电器方法(不再panic)
  15. func (t *TCPReader) CloseRelay1(validTime byte) error {
  16. frame := buildRelayFrame(0x0077, 1, RELAY_OP_CLOSE, validTime)
  17. _, err := t.SendAndRecv(frame)
  18. return err
  19. }
  20. func (t *TCPReader) ReleaseRelay1() error {
  21. frame := buildRelayFrame(0x0077, 1, RELAY_OP_RELEASE, 0)
  22. _, err := t.SendAndRecv(frame)
  23. return err
  24. }
  25. func (t *TCPReader) CloseRelay2(validTime byte) error {
  26. frame := buildRelayFrame(0x0078, 2, RELAY_OP_CLOSE, validTime)
  27. _, err := t.SendAndRecv(frame)
  28. return err
  29. }
  30. func (t *TCPReader) ReleaseRelay2() error {
  31. frame := buildRelayFrame(0x0078, 2, RELAY_OP_RELEASE, 0)
  32. _, err := t.SendAndRecv(frame)
  33. return err
  34. }
  35. func NewTCPReader(ip string, port int) *TCPReader {
  36. return &TCPReader{
  37. IP: ip,
  38. Port: port,
  39. }
  40. }
  41. func (t *TCPReader) Connect() error {
  42. addr := net.JoinHostPort(t.IP, string(rune(t.Port)))
  43. conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
  44. if err != nil {
  45. t.isConnected = false
  46. return err
  47. }
  48. t.conn = conn
  49. t.isConnected = true
  50. return nil
  51. }
  52. func (t *TCPReader) Disconnect() error {
  53. if t.conn != nil {
  54. _ = t.conn.Close()
  55. }
  56. t.isConnected = false
  57. t.buffer = nil
  58. return nil
  59. }
  60. func (t *TCPReader) IsConnected() bool {
  61. return t.isConnected
  62. }
  63. func (t *TCPReader) SendData(data []byte) error {
  64. if !t.isConnected {
  65. return errors.New("TCP未连接")
  66. }
  67. _, err := t.conn.Write(data)
  68. if err != nil {
  69. t.isConnected = false
  70. }
  71. return err
  72. }
  73. // ==============================
  74. // 🔥 关键修复:TCP 自动拼包,返回完整25字节帧
  75. // ==============================
  76. func (t *TCPReader) ReadData() ([]byte, error) {
  77. if !t.isConnected {
  78. return nil, errors.New("TCP未连接")
  79. }
  80. // 读超时,防止永久阻塞
  81. t.conn.SetReadDeadline(time.Now().Add(3 * time.Second))
  82. buf := make([]byte, 1024)
  83. n, err := t.conn.Read(buf)
  84. if err != nil {
  85. t.isConnected = false
  86. return nil, err
  87. }
  88. // 加入缓冲区
  89. t.buffer = append(t.buffer, buf[:n]...)
  90. // 找完整帧:0xCF 开头 + 25字节
  91. for len(t.buffer) >= 25 {
  92. if t.buffer[0] == 0xCF {
  93. frame := t.buffer[:25]
  94. t.buffer = t.buffer[25:]
  95. return frame, nil
  96. } else {
  97. t.buffer = t.buffer[1:]
  98. }
  99. }
  100. return nil, errors.New("等待完整帧")
  101. }
  102. func (t *TCPReader) SendAndRecv(data []byte) ([]byte, error) {
  103. if err := t.SendData(data); err != nil {
  104. return nil, err
  105. }
  106. t.conn.SetReadDeadline(time.Now().Add(3 * time.Second))
  107. return t.ReadData()
  108. }