我对这两个Protobufs都有一个很大的问题。
我使用Googles Protobuf在C ++上有一个服务器/客户端应用程序。 它运作得很好。
客户端将数据发送到应分发此消息的服务器 对其他客户。
C ++客户端是一个纯粹的发送者,将Protobuf-Struct打包成一个固定大小(500个大气压)的Char-Array。
C ++服务器对其进行反序列化,查找命令(登录注销或向其他人发送消息),以及(如果是消息)将其发送到C#-Client。 这也是通过固定大小的500个字符来完成的。
这很有效。 现在在C#方面:
C#client atm可以使用Protobuf-net登录并发送消息。尽管Protobuf-Net将它包装在一个字节数组(与c ++-side上的字符数组不同,它是无符号的)并且具有动态大小,但它的工作非常出色。 即使如此,服务器也会识别该消息并将其打印出来。
但是当服务器从c ++转发消息时,这是一个非常棘手的问题 - 客户端我在C#中遇到了大问题。
注意:客户端在Unity3D中实现。
Unity收到Byte-Array几乎没问题。 需要注意的一点是,与服务器发送的消息不同,字节数是无符号的。这导致-1变为255.
C#-Code:
char buffer[BUF];
package.serializeToArray(buffer,500);
int n = sendto(sock,buffer,BUF,0,(struct sockaddr*)
&serverAddr,sizeof(serverAddr));
这是C#客户端。
C ++ - 代码:
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 ++ - Server只是将char-Array转发给C#-client, 这与没有serialize-part的UDP-Client相同。
我得到的错误如下: ProtoException: 源数据中的字段无效:0
或Invalide wire-type
编辑: 这是Proto-File
{{1}}
对于C ++,我使用普通的Proto-Compiler 对于C#,我使用-Net编译器来创建CS文件 然后从它构建libary,参考ProtoBuf.dll进行统一 然后让预编译器将Serialize.dll包含在Unity3D中
答案 0 :(得分:0)
好的,我更好地重读了你的代码。我认为问题可能与您处理c#服务器的方式有关。我想你应该尝试这种方法:
MemoryStream stream = new MemoryStream(incoming,false);
ModelSerializer serializer = new ModelSerializer();
message =(SendPack)serializer.Deserialize(stream,incoming,typeof(incoming));
答案 1 :(得分:0)
好的。我现在找到了答案。
如果传入的消息具有固定长度(在我的情况下为500),如果它不是Protobuf的确切字节大小,则Protobuf-Net存在实际问题。
我用这种方式修改了我的C ++ - 服务器:
int size = package.ByteSize();
char message[size];
package.SerializeToArray(message,size);
然后以这个尺寸发送它。
正如我在OP中提到的,C ++版本可以 处理打包到修复大小的数组中的消息 并解码它们。
现在关于C#-Part我需要做一些工作。
我仍然收到一条消息并将其放入一个修复大小的字节数组中。 如果我只是使用未初始化的数组,我会收到错误。
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();
}