使用golang操作protobuf

本文介绍了如何使用Golang操作protobuf,从Protobuf语法到编写proto文件,再到编译和实际使用,包括proto2和proto3的语法,以及通过chat.proto文件生成chat.pb.go和实现server.go、client.go的应用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Protobuf语法

proto2语法

proto3语法

编写proto文件

chat.proto

syntax = "proto3";

package chat;

message ReqSendChatMsg
{
    string msg         = 1;
}

message ResSendChatMsg
{
    uint32 ret         = 1;
    string msg         = 2;
    uint32 timestamp   = 3;
}

编译proto文件

protoc --go_out=./  chat.proto

生成chat.pb.go文件

使用proto

server.go

package main

import (
	"fmt"
	"io"
	"net"
	"time"

	"github.com/golang/protobuf/proto"

	chat "XXX/XXX/chat"
)

func handle(conn net.Conn) {
	defer conn.Close()
	ip := conn.RemoteAddr().String()
	fmt.Printf("new client:%s\n", ip)
	for {
		buff := make([]byte, 128)
		bufflen, err := conn.Read(buff)
		if err == io.EOF {
			fmt.Printf("%s close\n", ip)
			return
		}
		if err != nil {
			fmt.Printf("%s read err:%s\n", ip, err.Error())
			continue
		}
		if bufflen > 0 {
			req := &chat.ReqSendChatMsg{}
			proto.Unmarshal(buff[0:bufflen], req)
			fmt.Printf("%s recv:%s\n", ip, req.GetMsg())

			res := &chat.ResSendChatMsg{}
			res.Ret = 200
			res.Msg = "正在处理您的请求"
			res.Timestamp = uint32(time.Now().Unix())
			data, err := proto.Marshal(res)
			if err != nil {
				fmt.Println(err)
				continue
			}
			conn.Write(data)
		}
	}
}

func main() {
	listen, err := net.Listen("tcp", "127.0.0.1:9999")
	if err != nil {
		fmt.Printf("tcp listen err:%s\n", err.Error())
		return
	}
	defer listen.Close()
	fmt.Println("tcp listen 127.0.0.1:9999")
	for {
		conn, err := listen.Accept()
		if err != nil {
			continue
		}
		go handle(conn)
	}
}

client.go

package main

import (
	"fmt"
	"io"
	"net"

	"github.com/golang/protobuf/proto"

	chat "XXX/XXX/chat"
)

func CreatConn(num int) {
	conn, err := net.Dial("tcp", "127.0.0.1:9999")
	if err != nil {
		fmt.Printf("dial err:%s\n", err.Error())
		return
	}
	defer conn.Close()
	for {
		fmt.Print("请输入聊天信息:")

		var msg string
		fmt.Scanf("%s", &msg)
		send := &chat.ReqSendChatMsg{}
		send.Msg = msg

		data, err := proto.Marshal(send)
		if err != nil {
			fmt.Printf("proto marshal err %s\n", err.Error())
			return
		}

		_, err = conn.Write(data)
		if err != nil {
			fmt.Printf("write err:%s\n", err.Error())
		}

		buff := make([]byte, 128)
		datalen, err := conn.Read(buff)
		if err == io.EOF {
			fmt.Println("server close")
			return
		}
		if err == nil && datalen > 0 {
			recv := &chat.ResSendChatMsg{}
			proto.Unmarshal(buff[0:datalen], recv)
			ret := recv.GetRet()
			msg := recv.GetMsg()
			if ret == 200 {
				fmt.Printf("recv server: %s\n", msg)
			}
		}
	}
}

func main() {
	CreatConn(1)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值