美文网首页
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 来进行数据交互

    介绍 这篇文章主要介绍如何使用 Protobuf 来在 Go 语言程序和 C++ 程序之间进行数据交互。这里使用 ...

  • Android 网络请求详解

    我们知道大多数的 Android 应用程序都是通过和服务器进行交互来获取数据的。如果使用 HTTP 协议来发送和接...

  • protobuf基础教程

    前端protobuf入门 此文只讲述web前端与后端使用protobuf进行数据交互的基础与入门教学,更加详细的内...

  • Lua与C++如何相互交互?

    Lua与C++如何相互交互 通过lua虚拟栈隔离Lua和C/C++类型和彼此内存的差异来实现数据及函数互相调拥。1...

  • C++ 基本语法

    C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。 对象 - 对象具有状态和行为。例如:一只狗...

  • 初识protobuf go语言版

    protobuf 一种二进制传输数据包 go的protobuf包go get github.com/golang/...

  • ProtoBuf

    Protobuf是目前移动端网络开发的主流数据交互协议. ProtoBuf也叫Google-protobuf,只支...

  • Hyperledger Fabric SDK学习

    学习背景: 我用SDK(go)用来进行Fabric 网络进行交互,通过SDK调用grpc与指定的peer节点和or...

  • miRPath:miRNA相关GO和KEGG功能分析

    欢迎关注”生信修炼手册”! 对于mRNA数据,我们经常通过GO和KEGG富集分析来进行功能分析,对于miRNA数据...

  • 第十八章:Go语言并发数据同步

    1. 概述 Go程序可以通过channel在多个goroutine 之间进行数据交换保障了数据正确性,但是chan...

网友评论

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

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