Go UDP服务端代码

package main

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"net"
)

type DataPacket struct {
	Type string
	Body string
}

func main() {
	//绑定端口
	tcpAddr, err := net.ResolveTCPAddr("tcp", ":19010")
	if err != nil {
		fmt.Println(err.Error())
	}
	//监听
	listener, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer listener.Close()
	//开始接收数据
	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println(err.Error())
		}
		go Handler(conn)
	}

}

func Handler(conn net.Conn) {
	defer conn.Close()
	//每次读取数据长度
	buf := make([]byte, 256)
	_, err := conn.Read(buf)
	if err != nil {
		return
	}
	result, Body := check(buf)
	if result {
		fmt.Printf("接收到报文内容:{%s}\n", hex.EncodeToString(Body))
	}

}

func check(buf []byte) (bool, []byte) {
	Length := DataLength(buf)
	if Length < 3 || Length > 256 {
		return false, nil
	}
	Body := buf[:Length]
	return uint16(len(Body))-2 != Length, Body
}

func DataLength(buf []byte) uint16 {
	return binary.BigEndian.Uint16(inversion(buf[:2])) + 2
}

//反转字节
func inversion(buf []byte) []byte {
	for i := 0; i < len(buf)/2; i++ {
		temp := buf[i]
		buf[i] = buf[len(buf)-1-i]
		buf[len(buf)-1-i] = temp
	}
	return buf
}


Go UDP客户端段代码


package main

import (
	"bufio"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"net"
	"os"
	"strings"
	"time"
)

func main() {

	//请求地址
	conn, err := net.Dial("udp", "127.0.0.1:30001")
	if err != nil {
		fmt.Println("net.Dial err:", err)
		return
	}
	//假设该设备序号
	SerialNumbe := "AA001D80"
	defer conn.Close()
	//这里是设备正常请求
	go func() {
		for {
			//报文长度占用俩个字节(报文长度不包含自身),类型1个字节,设备序列号4个字节
			decodeString, err := hex.DecodeString("050000" + SerialNumbe)
			if err != nil {
				fmt.Println("错误的16进制字符串!")
			}
			fmt.Printf("发送的心跳包:{%s}\n", ByteToHex(decodeString))
			conn.Write(decodeString)
			//心跳发送后,睡眠5秒
			time.Sleep(time.Duration(10) * time.Second)
		}
	}()
	//这里是其他操作
	go func() {
		input := bufio.NewScanner(os.Stdin)
		for input.Scan() {
			line := input.Text()
			fmt.Println(line)
			bytes, err := hex.DecodeString(line)
			if err != nil {
				//格式:
				//	报文长度,俩个字节(报文长度不包含自身)
				//	报文类型,一个字节
				// 	报文内容,自定义
				//例如:
				//	0300090023
				fmt.Println("请输入正确的16进制字符串!")
			} else {

				conn.Write(bytes)
			}
		}

	}()
	buf := make([]byte, 256)
	for {
		_, err := conn.Read(buf)
		if err != nil {
			fmt.Println("conn.Read err:", err)
			return
		}
		fmt.Printf("收到服务器心跳包返回:{%s}\n", ByteToHex(buf[:DataLength(buf)]))
		fmt.Print("请输入请求报文:\n")

	}

}

//字节转16进制字符串,并且字符转大写
func ByteToHex(buf []byte) string {
	return strings.ToUpper(hex.EncodeToString(buf))
}

func DataLength(buf []byte) uint16 {
	return binary.BigEndian.Uint16(inversion(buf[:2]))
}

//反转字节
func inversion(buf []byte) []byte {
	for i := 0; i < len(buf)/2; i++ {
		temp := buf[i]
		buf[i] = buf[len(buf)-1-i]
		buf[len(buf)-1-i] = temp
	}
	return buf
}


效果如下:

010002