无法通过UDP protobuf从c ++发送超过127的整数值到java

时间:2014-04-08 03:35:35

标签: java android c++ udp protocol-buffers

我正在尝试使用protobuf通过UDP发送int数据。从visual c ++到Java(Android Studio)

原型文件

message rbr
{
  required int32 rpm = 1;
  required int32 gear = 2;
  required int32 speed = 3;
}

C ++发送:

telemetry.set_rpm(1200);
telemetry.set_speed(120);
telemetry.set_gear(4);

telemetry.SerializeToString(&serializedMessage);

memset(message, '\0', BUFLEN);
memcpy(message, serializedMessage.c_str(), serializedMessage.size());


//send the message
if (sendto(s, message, serializedMessage.size(), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
   printf("sendto() failed with error code : %d", WSAGetLastError());
   exit(EXIT_FAILURE);
}

Java(Android)使用方线protobuff库接收:

socket = new DatagramSocket(8888);

Wire wire = new Wire();

while (true) {
    packet = new DatagramPacket(buf, buf.length);
    socket.receive(packet); 
    s = new String(packet.getData(), 0, packet.getLength());

    byte[] bytes = s.getBytes();
    rbr newMsg = wire.parseFrom(bytes, rbr.class);

    sGear = newMsg.gear.toString();
    sRpm = String.valueOf(newMsg.rpm);
    sSpeed = newMsg.speed.toString();   

    tvRpm.post(new Runnable() {
        public void run() {
            tvRpm.setText(sRpm);
            tvGear.setText(sGear);
            tvSpeed.setText(sSpeed);
        }
    });
}

如果值低于127,则正确接收数据,当我发送128时,结果为3104751.但是当我尝试在Visual C ++中接收它时,它工作正常。

更新代码以使用SerilizeToArray

int size = telemetry.ByteSize();
char* array = new char[size];
telemetry.SerializeToArray(array, size);        
memset(message, '\0', BUFLEN);  
memcpy(message, array, size);

但是如何在java上接收?我尝试这个代码,但没有工作。

packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);                    
byte[] bytes = packet.getData();
rbr newMsg = wire.parseFrom(bytes, rbr.class);

2 个答案:

答案 0 :(得分:0)

使用字符串作为字节数组持有者并调用String.getBytes()是一种不好的做法,总是会导致代码损坏。

您在C ++端使用Message.SerializeToString,因此您应该在Java端使用类似com.google.protobuf.TextFormat.merge(CharSequence,MessageBuilder)的内容来解析protobuf文本格式。

更好的是,而不是文本格式使用正常的二进制表示。生成的消息和构建器类提供直接与字节数组(以及Java中的流)一起工作的序列化和反序列化方法,并且通过UDP发送和接收字节数组(可以说)更自然,然后将某些内容转换为字符串然后转换为字符串到字节数组并返回。

答案 1 :(得分:0)

我发现它,oleg是对的,问题是因为我将它转换为字符串。现在我直接从包中复制字节。

byte[] bytes = Arrays.copyOfRange(packet.getData(),0,packet.getLength());