繁体   English   中英

无法通过UDP protobuf从C ++向Java发送大于127的整数值

[英]Can't send integer value more than 127 from c++ to java via UDP protobuf

我正在尝试使用protobuf通过UDP发送int数据。 从视觉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)使用方线原型库接收:

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);

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM