go语言使用protobuf与c++做数据通信。

来源:互联网 发布:若尔盖网店美工招聘 编辑:程序博客网 时间:2024/05/29 03:58

首先,安装google的protobuf。安装流程请参见我以前的博客

http://blog.csdn.net/eclipser1987/article/details/8525383


安装proto的go语言插件

go get code.google.com/p/goprotobuf/{proto,protoc-gen-go}


编写一个简单的事例,go与c++网络通信:

RegMessage.proto

package cn.vicky.model.seri;message RegMessage {    required int32 id = 1; // 主键,唯一    required string username = 2; // 帐号    required string password = 3; // 密码    optional string email = 4; // 邮箱(可选)}


执行:
protoc --cpp_out=. RegMessage.proto

protoc --go_out=. RegMessage.proto


生成对应的c++源文件和go源文件

RegMessage.pb.h

RegMessage.pb.cc

RegMessage.pb.go


go语言做客户端代码:

// Code generated by protoc-gen-go.// source: RegMessage.proto// DO NOT EDIT!package mainimport "fmt"import "os"import "net"import proto "code.google.com/p/goprotobuf/proto"import json "encoding/json"import math "math"// Reference proto, json, and math imports to suppress error if they are not otherwise used.var _ = proto.Marshalvar _ = &json.SyntaxError{}var _ = math.Inftype RegMessage struct {Id               *int32  `protobuf:"varint,10001,req,name=id" json:"id,omitempty"`Username         *string `protobuf:"bytes,2,req,name=username" json:"username,omitempty"`Password         *string `protobuf:"bytes,3,req,name=password" json:"password,omitempty"`Email            *string `protobuf:"bytes,4,opt,name=email" json:"email,omitempty"`XXX_unrecognized []byte  `json:"-"`}func (m *RegMessage) Reset()         { *m = RegMessage{} }func (m *RegMessage) String() string { return proto.CompactTextString(m) }func (*RegMessage) ProtoMessage()    {}func (m *RegMessage) GetId() int32 {if m != nil && m.Id != nil {return *m.Id}return 0}func (m *RegMessage) GetUsername() string {if m != nil && m.Username != nil {return *m.Username}return ""}func (m *RegMessage) GetPassword() string {if m != nil && m.Password != nil {return *m.Password}return ""}func (m *RegMessage) GetEmail() string {if m != nil && m.Email != nil {return *m.Email}return ""}func init() {}func main() {regMessage := &RegMessage{Id:       proto.Int32(10001),Username: proto.String("vicky"),Password: proto.String("123456"),Email:    proto.String("eclipser@163.com"),}buffer, err := proto.Marshal(regMessage)if err != nil {fmt.Printf("failed: %s\n", err)return}pTCPAddr, err := net.ResolveTCPAddr("tcp", "192.168.1.98:7070")if err != nil {fmt.Fprintf(os.Stderr, "Error: %s", err.Error())return}pTCPConn, err := net.DialTCP("tcp", nil, pTCPAddr)if err != nil {fmt.Fprintf(os.Stderr, "Error: %s", err.Error())return}pTCPConn.Write(buffer)}

正常情况下是不建议修改protoc生成的源文件的,我们这里图省事,直接在生成的RegMessage.pb.go添加网络发送代码。

使用C++编写简单的socket服务器:


/*  * File:   main.cpp * Author: Vicky.H * Email:  eclipser@163.com */#include <cstdio>#include <cstdlib>#include <iostream>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <pthread.h>#include "RegMessage.pb.h"void* connHandler(void *pConn) {    int* _pConn = static_cast<int*> (pConn);    for (;;) {        void* buf = malloc(1024);        int n = read(*_pConn, buf, 1024);                cn::vicky::model::seri::RegMessage regMessage;        regMessage.ParseFromArray(buf, n);                std::cout << regMessage.id() << std::endl;        std::cout << regMessage.username() << std::endl;        std::cout << regMessage.password() << std::endl;        std::cout << regMessage.email() << std::endl;                close(*_pConn);        free(buf);    }    return pConn;}/* *  */int main(void) {    int sock = socket(AF_INET, SOCK_STREAM, 0);    if (sock == -1) {        perror("创建Socket失败!");        return EXIT_FAILURE;    }    struct sockaddr_in addr;    addr.sin_port = htons(7070);    inet_pton(AF_INET, "192.168.1.98", &addr.sin_addr);    int result;    result = bind(sock, (struct sockaddr*) &addr, sizeof (struct sockaddr_in));    if (result != 0) {        perror("绑定地址失败!");        return EXIT_FAILURE;    }    result = listen(sock, 10);    if (result != 0) {        perror("监听失败!");        return EXIT_FAILURE;    }    for (;;) {        int conn = accept(sock, NULL, NULL);        if (conn == -1) {            perror("与客户端建立连接失败!");            continue;        }        pthread_t thread;        pthread_create(&thread, NULL, connHandler, (void*) &conn);    }    return 0;}


需要连接 -lpthread -lprotobuf 


分别运行c++程序,go run RegMessage.pb.go

打印:

1
vicky
123456
eclipser@163.com

0 0
原创粉丝点击