//客户端:
package main
import (
"bytes"
"encoding/binary"
"fmt"
"net"
)
type rpc_detail struct{
Version [2]byte //版本号
FunsLen uint32 //函数名长度
FunsName []byte
}
func main() {
obj := new(rpc_detail)
conn ,err := net.Dial("tcp",":33122")
data := "get_data_detail-%d"
for i:=0;i < 1;i++{
send_data := fmt.Sprintf(data,i)
(*obj).Version[0] = 'v'
(*obj).Version[1] = '1'
(*obj).FunsLen = uint32(len(send_data))
(*obj).FunsName = []byte(send_data)
fmt.Printf("结构体:%+v\n",*obj)
buf := new(bytes.Buffer)
binary.Write(buf,binary.BigEndian,obj.Version)
binary.Write(buf,binary.BigEndian,obj.FunsLen)
binary.Write(buf,binary.BigEndian,obj.FunsName)
conn.Write(buf.Bytes())
fmt.Printf("输出:%+v,err:%+v\n",buf.Bytes(),err)
}
}
//服务端接收socket
package main
import (
"fmt"
"net"
"bytes"
"encoding/binary"
"os"
"io"
)
func main() {
listener, err := net.Listen("tcp", ":33122")
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
defer listener.Close()
fmt.Println("Server started, listening on port 33122")
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
continue
}
go handleConnection(conn)
}
}
type rpc_detail struct{
Version [2]byte //版本号
FunsLen uint32 //函数名长度
FunsName []byte
}
func unpack(b []byte)(obj *rpc_detail){
buf := bytes.NewReader(b)
obj = new(rpc_detail)
err := binary.Read(buf,binary.BigEndian,&obj.Version)
fmt.Printf("错误:%+v,版本:%+c%+c\n",err,(*obj).Version[0],(*obj).Version[1])
err = binary.Read(buf,binary.BigEndian,&(*obj).FunsLen)
fmt.Printf("错误:%+v,函数名长度:%+v\n",err,(*obj).FunsLen)
return
}
func handleConnection(conn net.Conn) {
defer conn.Close()
data := make([]byte,6)
//dataBuffer := bytes.NewReader(binaryData)
for {
_, err := io.ReadFull(conn, data)
if err != nil {
if err == io.EOF {
fmt.Println("Client disconnected")
return
} else {
fmt.Println("Error reading from client:", err.Error())
return
}
}
obj := unpack(data)
body_len := obj.FunsLen
body_buf := make([]byte,body_len)
_, err = io.ReadFull(conn, body_buf)
buf := bytes.NewReader(body_buf)
err = binary.Read(buf,binary.BigEndian,&(*obj).FunsName)
fmt.Printf("body_buf:%+v,主体:%+v,err:%+v\n",body_buf,(*obj).FunsName,err)
}
}
我在通过binary.Read以大端的形式读取buf到rpc_detail.FunsName,但(*obj).FunsName的打印为空,body_buf打印结果为:[103 101 116 95 100 97 116 97 95 100 101 116 97 105 108 45 48],为什么binary.Reads对(*obj).FunsName转换不成功,而Version、FunsLen都可以解析出来
golang tcp拆包到结构体成员
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
3条回答 默认 最新
阿里嘎多学长 2025-10-14 10:56关注阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程
解决方案
你想要在 Go 语言中使用 TCP 协议进行通信,并将接收到的数据拆包到结构体成员中。这里是一个示例代码:
package main import ( "bytes" "encoding/binary" "fmt" "net" ) // rpc_data 结构体 type rpc_data struct { Field1 uint32 Field2 uint32 Field3 uint32 } func main() { // 创建 TCP 连接 conn, err := net.Dial("tcp", "localhost:8080") if err != nil { fmt.Println(err) return } defer conn.Close() // 发送数据 data := rpc_data{ Field1: 1, Field2: 2, Field3: 3, } buf := new(bytes.Buffer) err = binary.Write(buf, binary.LittleEndian, data) if err != nil { fmt.Println(err) return } _, err = conn.Write(buf.Bytes()) if err != nil { fmt.Println(err) return } // 接收数据 var receivedData rpc_data err = binary.Read(conn, binary.LittleEndian, &receivedData) if err != nil { fmt.Println(err) return } fmt.Println(receivedData) }在这个示例中,我们定义了一个
rpc_data结构体,并使用binary.Write和binary.Read函数来将结构体成员写入和读出 TCP 流中。注意我们使用了LittleEndian字节序来匹配 TCP 流中的数据。注意
- 这个示例假设 TCP 服务端已经实现了数据的发送和接收逻辑。
- 在实际应用中,需要考虑数据的校验和错误处理逻辑。
解决 无用评论 打赏 举报