Golang UDP通信案例
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
服务端收到后显示: