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
服務端收到后顯示: