美文网首页
Go 和 C++ 程序通过 protobuf 来进行数据交互

Go 和 C++ 程序通过 protobuf 来进行数据交互

作者: juniway | 来源:发表于2017-12-16 16:58 被阅读411次

    介绍

    这篇文章主要介绍如何使用 Protobuf 来在 Go 语言程序和 C++ 程序之间进行数据交互。
    这里使用 Go 编写服务端,而用 C++ 编写客户端。

    编写 proto 协议文件

    在开始写客户端和服务端之前,首先需要生成 Go 和 C++ 的 proto 协议文件,只编写一个 proto 文件即可。
    新建一个名为 msg.proto 的文件,输入如下内容:

    syntax = "proto3";
    package msg;
    
    message Msg {
        int64 MsgId = 1;
        string MsgInfo = 2;
        string MsgFrom = 3;
    }
    

    编译 proto 文件

    执行下列命令分别生成 Go 语言和 C++ 对应的文件

    protoc --cpp_out=. msg.proto
    protoc --go_out=. msg.proto
    

    编写 Go 服务端程序

    package main
    import (
        "fmt"
        "os"
        "net"
        
        "test/msg"
        
        "github.com/google/protobuf/proto"
    )
    func handleConn(conn net.Conn) {
        defer conn.Close()
        buf := make([]byte, 128)
        n, err := conn.Read(buff)
        if err != nil {
            fmt.Println("read data failed...")
            return
        }
        fmt.Printf("read len: %d\n", ReadLen)
        fmt.Println(buff)
        
        msgBuf := buf[0 : n]
        reciveMsg := &msg.Msg {}
        
        err = proto.Unmarshal(msgBuf, reciveMsg)
        if err != nil {
            fmt.Printf("unmarshaling error: ", reciveMsg)
        }
        fmt.Printf("msg id: %d\n", reciveMsg.GetMsgId())
        fmt.Printf("msg info: %s\n", reciveMsg.GetMsgInfo())
        fmt.Printf("msg from id: %s\n", reciveMsg.GetMsgFrom())
    }
    
    func main() {
        tcpAddr, err := net.ResolveTCPAddr("tcp4", ":2121")
        if err != nil {
            fmt.Println("get tcp addr failed...")
            return
        }
        listener, err := net.ListenTCP("tcp", tcpAddr)
        if err != nil {
            fmt.Println("listen tcp failed...")
            return
        }
        for {
            conn, err := listener.Accept()
            if err != nil {
                continue
            }
            go handleConn(conn)
        }
    }
    

    编写 C++ 客户端程序

    #include "msg.pb.h"
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <cstring>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char *argv[]){
        
        int sk = socket(AF_INET, SOCK_STREAM, 0);
        
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(2121); // 固定端口port
        server.sin_addr.s_addr = inet_addr("127.0.0.1"); // 固定ip
        
        connect(sk, (struct sockaddr*)&server, sizeof(server));
        
        msg::Msg sendMsg;
        sendMsg.set_msgid(0);
        sendMsg.set_msginfo("hello protobuf");
        sendMsg.set_msgfrom("alex");
        
        string sendData;
        sendMsg.SerializeToString(&sendData);
        int len = sendData.length();
        cout << "string len:" << len << endl;
        
        char *buff = new char[len + 1];
        memcpy(buff, sendData.c_str(), len);
        
        cout << "buff len:" << strlen(buff) << endl;
        //向服务段发送数据
        //在发送数据时一定要指明数据长度 防止中间有\0截断c风格字符串
        send(sk, buff, len, 0);
        close(sk);
        return 0;
    }
    

    运行

    先后启动服务端和客户端程序

    相关文章

      网友评论

          本文标题:Go 和 C++ 程序通过 protobuf 来进行数据交互

          本文链接:https://www.haomeiwen.com/subject/kfaswxtx.html