c++ java 用protobuf通讯

来源:互联网 发布:手绘自拍软件 编辑:程序博客网 时间:2024/06/06 04:02

http://www.cnblogs.com/royenhome/archive/2010/10/30/1865153.html

c++端

using namespace::google::protobuf::io;

#define  MAX_SIZE 4096

//序列化

char tmpArr[MAX_SIZE];
    memset(tmpArr,0,sizeof(tmpArr));
    ZeroCopyOutputStream *raw_output = new ArrayOutputStream(tmpArr,addressBook.ByteSize()+1);    
    CodedOutputStream* coded_output = new CodedOutputStream(raw_output);    
    if( !addressBook.SerializeToCodedStream( coded_output ))
    {
        cerr<<"Fail to serial addressbook data!\n";
        return;
    }    
    send(socketfd,tmpArr,addressBook.ByteSize(),0);
    cout<<"serial address successfully!\n";
    delete coded_output;
    delete raw_output;  

//反序列化

numbytes = recv(soxketfd, buf, MAX_SIZE, 0);

demo::People p;
p.Clear();


    if( !p.ParseFromArray(buf,numbytes) )
    {
        cerr<<"Deserial from addressbook.data failed!\n";
        return 0;
    }

 

Java 端

//序列化

 socket = new Socket("192.168.51.46", 12345);

 People people=People.newBuilder().setId(0)
     .setName("Hideto").setEmail("Hideto@gmail.com").build();
 

 people.writeTo(socket.getOutputStream());

 
 socket.getOutputStream().flush();

//

People.toByteArray();

 

//反序列化

 //parseFrom是静态方法

//类型确定是People

people=People.parseFrom(socket.getInputStream());

 

//类型不确定,由类型的名字,重构message

Package demo中的Class Demo的嵌套类People

className="demo.Demo$People";

 public Object objectFromByteBuffer(String className, byte[] buffer)
   throws Exception {  
  Class clazz = Class.forName(className);
  // Thread.currentThread().getContextClassLoader().loadClass(className);
 
  Method parseFromMethod = clazz.getMethod("parseFrom", byte[].class);
  return parseFromMethod.invoke(null, buffer);

 }

//类型不确定,由Descriptor 产生 DynamicMessage

protoc --descriptor_set_out=demo.desc demo.proto

 

 Map<String, String> mapping = new HashMap<String, Descriptor >();

建立Map保存名字和Descriptor 的映射

 

 void init() {

  try {
   try {
    FileInputStream fs = new FileInputStream("src/demo");
    FileDescriptorSet descriptorSet = FileDescriptorSet
      .parseFrom(fs);

    for (FileDescriptorProto fdp : descriptorSet.getFileList()) {

     FileDescriptor fd = FileDescriptor.buildFrom(fdp,
       new FileDescriptor[] {});

     for (Descriptor descriptor : fd.getMessageTypes()) {
      String className = fdp.getOptions().getJavaPackage()
        + "."
        + fdp.getOptions().getJavaOuterClassname()
        + "$" + descriptor.getName();
      mapping.put(descriptor.getFullName(), descriptor );
     }
    }
   } catch (IOException e) {
    System.out.println(e.toString());
   }
  } catch (Exception e) {
   System.out.println(e.toString());
  }

 }

由名字得到相应的descriptor,然后

 public Object objectFromByteBuffer(Descriptor descriptor, byte[] buffer)
   throws Exception {

  ByteArrayInputStream bais = new ByteArrayInputStream(buffer);

  int n = bais.read();
  byte[] message = new byte[n];

  // 由className得到相应的descriptor
  DynamicMessage m = DynamicMessage.parseFrom(descriptor, message);
  return m;
 }

 

/////////////////////////////////////////////////////////////////////////////////

People people;

string a;

p.set_id(0);

 p.set_name("a");

p.set_email("a@a.net");

p.SerializeToString(&a);

p.ParseFromString(a);

p.set_id(123);序列化,反序列化都正常。

p.set_id(0);会丢失email数据。

原因:p.set_id(0);使string中出现了字符0.

0 0
原创粉丝点击