0
点赞
收藏
分享

微信扫一扫

c++ 通过socket protobuf 传送vector 结构体数据

天悦哥 2022-02-25 阅读 116

参考:

  1. protobuf 使用link
  2. 专注于中台化代码生成器link
  3. protobuf repeated的用法link
  4. 深入浅出:如何正确使用 protobuflink
  5. How to add vector to repeated field protobuf c++link
  6. Ubuntu下使用protobuf和socket实现服务器间消息传输link
  7. Protobuf的C++使用笔记link
  8. Protobuf学习笔记(二)proto类与vector,数组的相互转换link
  9. protobuf中repeated类型变量与C++ vector类型变量的相互赋值方法link
  10. 链接protobuf遇到的一个坑,记录下来备忘一下link
  11. 如何停止使用Protobuf 3输出错误消息“Can’t parse message of type because it is missing required fields”?link
  12. 将字符串数组清空的操作link

代码:

  1. ch128driver.proto
syntax = "proto2";
package PointFrame;

message PointXYZRGBA_PROTO{
  optional float x = 1;
  optional float y = 2;
  optional float z = 3;
  optional int32 a = 4;
  optional int32 r = 5;
  optional int32 g = 6;
  optional int32 b = 7;
};
message POINTS_PROTO{
  repeated PointXYZRGBA_PROTO myPointXYZRGBA_PROTO = 1;
  required int32 curtime = 2;
}
  1. cmakelist.txt
cmake_minimum_required(VERSION 3.5)
PROJECT (protobuf_socket_test)
add_definitions(-std=c++11)

# Find required protobuf package
find_package(Protobuf REQUIRED)
if(PROTOBUF_FOUND)
    message(STATUS "protobuf library found")
else()
    message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()

include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ch128driver.proto)


ADD_EXECUTABLE(client client.cpp ${PROTO_SRCS} ${PROTO_HDRS})
target_link_libraries(client ${PROTOBUF_LIBRARIES})

ADD_EXECUTABLE(server server.cpp ${PROTO_SRCS} ${PROTO_HDRS})
target_link_libraries(server ${PROTOBUF_LIBRARIES})
  1. client.cpp
#include <iostream>
#include <string>
#include <ctime>
//for protobuf
#include "ch128driver.pb.h"
#include "utils.h"
//for socket
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

using namespace std;
//using namespace Test::protobuf ;

const int BUFFSIZE = 40000*32;

int main()
{
    //建立socket
    int socketfd ;
    struct sockaddr_in seraddr ;
    string hostip = "127.0.0.1";

    if((socketfd = socket(AF_INET,SOCK_STREAM,0)) > 0)
    {
        cout<<"create socket success..."<<endl;
    }
    //地址置空
    bzero( &seraddr, sizeof(seraddr) );
    //
    seraddr.sin_family = AF_INET ;
    seraddr.sin_port = htons(9998);
    seraddr.sin_addr.s_addr = inet_addr(hostip.c_str());
    //尝试连接到服务端地址
    if(connect(socketfd,(struct sockaddr *)&seraddr, sizeof(seraddr)) < 0)
    {
        cout<<"connect to server failed ..."<<endl;
        close(socketfd);
        return -1;
    }


    PointFrame::PointXYZRGBA_PROTO mypointxyzrgba;

    PointFrame::POINTS_PROTO mypoint_pro;
//    std::vector<PointFrame::PointXYZRGBA_PROTO> vp;

    std::vector<PointFrame::PointXYZRGBA_PROTO> vp;
    while(1)
    {
        int curtime = time(NULL) ;

        cout << "mypointxyzrgba.ByteSizeLong() :" << mypointxyzrgba.ByteSizeLong() << endl;
        cout << "mypoint_pro.ByteSizeLong()  " << mypoint_pro.ByteSizeLong() << endl;

        mypointxyzrgba.set_x(curtime*0.001);
        mypointxyzrgba.set_y(curtime*0.002);
        mypointxyzrgba.set_z(curtime*0.003);
        mypointxyzrgba.set_a(234);
        mypointxyzrgba.set_g(56);
        mypointxyzrgba.set_r(35);
        mypointxyzrgba.set_b(12);
        vp.push_back(mypointxyzrgba);

        mypoint_pro.set_curtime(curtime);
        mypoint_pro.mutable_mypointxyzrgba_proto()->CopyFrom({vp.begin(),vp.end()});

        char buff[BUFFSIZE];
//        std::string msg;
        mypoint_pro.SerializeToArray(buff,BUFFSIZE);
        cout << "mypoint_pro.ByteSizeLong() " << mypoint_pro.ByteSizeLong() << endl;
        cout << "sizeof(buff) :" << sizeof(buff) << endl;
        cout << "strlen(buff) :" << strlen(buff) << endl;
        if(send(socketfd,buff,strlen(buff),0) < 0)
        {
            cout<<curtime<<": send failed ..."<<endl;
            break;
        }


        cout<<curtime<<": send success ..."<<endl;
        sleep(2); //每隔2s发送一次
        vp.clear();
    }
    close(socketfd);
    return 0;
}

  1. server.cpp
#include <iostream>
#include <string>
#include <ctime>
#include <cerrno>
//for protobuf
#include "ch128driver.pb.h"
#include "utils.h"
//for socket
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>

#include <unistd.h>  // problem solved! it compiles!

using namespace std;
//using namespace Test::protobuf ;

const int BUFFSIZE = 40000*32;
const int QLEN = 10 ;

int main()
{

    int listenfd ;
    int connfd ;
    struct sockaddr_in seraddr ;
    //建立socket
    //AF_INET:IPv4因特网域
    //SOCK_STREAM:TCP链接
    //0:给定前两个参数,选择默认的协议
    listenfd = socket(AF_INET,SOCK_STREAM,0);
    if(listenfd < 0 )
    {
        cout<<"socket failed"<<endl;
    }
    //地址置空
    bzero(&seraddr,sizeof(seraddr));
    //
    seraddr.sin_family = AF_INET ;
    seraddr.sin_port = htons(9998);
    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    //关联地址和套接字
    if(bind(listenfd,(struct sockaddr *)&seraddr, sizeof(seraddr)) < 0)
    {
        cout<<"bind address with socket failed..."<<endl;
        close(listenfd);
        return -1;
    }
    //调用listen,宣告server愿意接受链接请求
    if(listen(listenfd,QLEN) == -1)
    {
        cout<<"listen on socket failed..."<<endl;
        close(listenfd);
        return -1;
    }
    //获得连接请求,并建立连接
    if( (connfd = accept(listenfd,(struct sockaddr *)NULL,NULL)) < 0 )
    {
        cout<<"accept the request failed"<<endl;
        close(listenfd);
        return -1;
    }
    //HeartInfo myprotobuf;
    PointFrame::PointXYZRGBA_PROTO mypointxyzrgba;
    //char buff[BUFFSIZE];
    //std::vector<POINTXYZRBA> svp;

    //PointXYZRGBA mypoint;
    PointFrame::POINTS_PROTO mypoint_pro;
    std::vector<PointFrame::PointXYZRGBA_PROTO> svp;

    char buff[BUFFSIZE];


    while(1) {
        ;
//        cout << "sizeof(buff): " << sizeof(buff) << endl;
//        cout << "strlen(buff): " << sizeof(buff) << endl;
        if (recv(connfd, buff, sizeof(buff), 0) < 0) {
            cout << "recv failed ..." << endl;
            break;
        }
        cout << "recv scucess ..." << endl;


        mypoint_pro.ParseFromArray(buff,BUFFSIZE);
        cout << mypoint_pro.ByteSize() << endl;

        cout << mypoint_pro.mypointxyzrgba_proto().size()<< endl;
        cout << svp.size() << endl;
        cout << mypoint_pro.mypointxyzrgba_proto().Capacity() << endl;
//        cout << ((PointFrame::PointXYZRGBA_PROTO)svp.at(0)).a() << endl;
        cout << mypoint_pro.mypointxyzrgba_proto().data()<< endl;


        //cout << mypoint_pro.mypointxyzrgba_proto().<< endl;
        svp.insert(svp.end(), mypoint_pro.mypointxyzrgba_proto().begin(), mypoint_pro.mypointxyzrgba_proto().end());
        cout << mypoint_pro.curtime() <<" "  << svp.at(0).x() <<" " << svp.at(0).y() <<" " <<svp.at(0).z() <<" " <<svp.at(0).a()<<  svp.at(0).r()<<" " << svp.at(0).g() <<" "<<svp.at(0).b() << endl;
        svp.clear();
        bzero(buff, sizeof(buff));
    }
    close(listenfd);
    close(connfd);
    return 0;
}

  1. utils.h
//
// Created by wx on 2022/2/23.
//

#ifndef PROTOBUF_SOCKET_TEST_UTILS_H
#define PROTOBUF_SOCKET_TEST_UTILS_H
typedef struct POINTXYZRBA
{
    float x;
    float y;
    float z;
    int a;
    int r;
    int g;
    int b;
}PointXYZRGBA;
#endif //PROTOBUF_SOCKET_TEST_UTILS_H
举报

相关推荐

0 条评论