首页 文章

谷歌上的Googles ProtoBuf与C#(UDP)上的Protobuf-net聊天

提问于
浏览
1

我对这两个Protobufs都有一个很大的问题 .

我使用Googles Protobuf在C上有一个服务器/客户端应用程序 . 它运作得很好 .

客户端将数据发送到服务器,服务器应将此消息分发给其他客户端 .

C客户端是纯发送器,将Protobuf-Struct打包成具有固定大小(500个大气压)的Char-Array .

C服务器对其进行反序列化,查找命令(登录注销或向其他人发送消息),以及(如果是消息)将其发送到C#-Client . 这也通过固定大小的500个字符来完成 .

这非常有效 . 现在在C#方面:

C#客户端atm可以使用Protobuf-net登录并发送消息 . 尽管Protobuf-Net将它包装在一个字节数组(与c-Side上的字符数组不同,它是无符号的)并且具有动态大小,但它的工作非常出色 . 即使如此,服务器也会识别该消息并将其打印出来 .

但是,当服务器从c -Client转发消息时,我发现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 -Client

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我使用普通的Proto-Compiler For C#我使用-Net编译器创建一个CS-File然后从它创建libary,参考ProtoBuf.dll for unity,然后让预编译器生成一个Serialize.dll以包含在Unity3D中

2 回答

  • 0

    好的,我更好地重读了你的代码 . 我认为问题可能与您处理c#服务器的方式有关 . 我想你应该尝试这种方法:

    MemoryStream stream = new MemoryStream(incoming,false);
    ModelSerializer serializer = new ModelSerializer(); message =(SendPack)serializer.Deserialize(stream,incoming,typeof(incoming));

  • 0

    行 . 我现在找到了答案 .

    如果传入消息具有固定长度(在我的情况下为500),如果它不是Protobuf的确切字节大小,则Protobuf-Net存在实际问题 .

    我用这种方式修改了我的C -Server:

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

相关问题