Googles ProtoBuf在C ++上与Protobuf聊天
对于这两种Protobufs我都有一个很大的问题。
我有一个使用Googles Protobuf的C ++上的服务器/客户端应用程序。 它工作得很好。
客户端将数据发送到服务器,该服务器应该将此消息分发给其他客户端。
C ++ Client是一个纯粹的发送者,将Protobuf-Struct封装在固定大小(500个大气压)的Char-Array中。
C ++ Server将其反序列化,查找命令(登录注销或其他消息),以及(如果其消息)将其发送到C#-Client。 这也是由500个字符的固定大小完成的。
这工作得很好。 现在在C#端:
C#客户端atm可以登录并通过Protobuf-net发送消息。 这个工程即使protobuf网包它在一个字节数组(这是C ++的字符数组不像无符号 - 侧)相当辉煌与dyanamic大小。 即使如此,服务器也能识别该消息并将其打印出来。
但(这里是令人毛骨悚然的问题),当服务器转发来自c + +的消息 - 客户端我在C#中遇到大问题。
注意:客户端在Unity3D中实现。
Unity收到的字节数组几乎没问题。 需要注意的一点是,Byte-Array与服务器发送的消息不同,无符号。 这导致-1变成255。
C#-Code:
sock.ReceiveFrom (incoming, ref otherEnd);
SendPack message;
using(System.IO.MemoryStream ms =
new System.IO.MemoryStream(incoming)){
message = ProtoBuf.Serializer.Deserialize<SendPack>(ms);
print (message);
ms.Flush();
ms.Close();
}
这是C#客户端。
C ++ - 代码:
char buffer[BUF];
package.serializeToArray(buffer,500);
int n = sendto(sock,buffer,BUF,0,(struct sockaddr*)
&serverAddr,sizeof(serverAddr));
这是C ++ - 客户端
C ++ - Server只是将char-Array转发给C#-client,这与没有serialize-part的UDP-Client相同。
我得到像这样的错误:ProtoException:源数据中的无效字段:0
或残疾人线型
编辑:这是原始文件
syntax = "proto2"; package Messages;
message SendPack {
required int32 command = 1;
required string name = 2;
repeated RobotPart content = 3;
}
message RobotPart {
required float yaw = 1;
required float pitch = 2;
required float roll = 3;
}
对于C ++我用的是正常原编译器对于C#我用-Net编译器创建一个CS-文件然后从中构建libary,参照ProtoBuf.dll团结,然后让预编译器做一个Serialize.dll在Unity3D包括
好的,我更好地重读了你的代码。 我认为这个问题可能与你处理C#服务器的方式有关。 我认为你应该尝试这种方法:
MemoryStream stream = new MemoryStream(incoming,false);
ModelSerializer serializer = new ModelSerializer(); message =(SendPack)serializer.Deserialize(stream,incoming,typeof(incoming));
好吧。 我现在找到了答案。
如果传入消息具有固定的长度(在我的情况下为500),Protobuf-Net会遇到实际问题,如果它不是Protobuf的确切字节大小。
我以这种方式修改了我的C ++ - Server:
int size = package.ByteSize();
char message[size];
package.SerializeToArray(message,size);
然后用这个尺寸发送它。
正如我在OP中提到的那样,C ++版本可以处理打包到固定大小数组中的消息并对它们进行解码。
现在在C#中,我需要做一些小小的工作。
我仍然收到一条消息并将其放入修复大小的字节数组中。 如果我只是使用未初始化的数组,我会收到错误。
int s = sock.ReceiveFrom (incoming, ref otherEnd);
SendPack message = new SendPack();
using(System.IO.MemoryStream ms = new System.IO.MemoryStream(incoming,0,s)){
SendPackSerializer sps = new SendPackSerializer();
message = (SendPack)sps.Deserialize(ms,null,typeof(SendPack));
print (message);
ms.Flush();
ms.Close();
}
链接地址: http://www.djcxy.com/p/42559.html