2016-06-28 4 views
1

私はProtobufsに関して大きな問題があります。Googles ProtoBuf on C++でProtobuf-netとチャット(UDP)

私は、Googles Protobufを使用してC++でサーバー/クライアントアプリケーションを使用しています。 非常にうまく動作します。

クライアントは、このメッセージ を他のクライアントに配布する必要があるサーバーにデータを送信します。

C++クライアントは、Protobuf-Structを固定サイズ(500気圧)のChar-Arrayにパックする純粋な送信者です。

C++サーバはそれをデシリアライズし、コマンド(ログインログアウトまたは他のユーザへのメッセージ)と(メッセージの場合)C#-Clientに送信します。 これは固定サイズの500文字でも行われます。

これは非常にうまくいきます。 C#側にあります。

C#クライアントatmはProtobuf-netでログインしてメッセージを送信できます。これはProtobuf-Netがダイナミックサイズのバイト配列(これはC++のSideのchar配列とは違って符号なし)にパックしていても非常に鮮明です。 それでも、サーバーはメッセージを認識して印刷します。

サーバがC++クライアントからメッセージを転送するとき(ただし、ここで問題が起きます)、C#で大きな問題が発生します。

注:クライアントはUnity3Dで実装されています。

Unityは、ほとんどの場合、バイト配列を受け取ります。 Byte-Arrayは、サーバーから送信されたメッセージとは異なり、署名されていません。これはにつながる-1 255

C#-codeになる:これはC#のクライアントである

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++ - コード:

char buffer[BUF]; 
package.serializeToArray(buffer,500); 
int n = sendto(sock,buffer,BUF,0,(struct sockaddr*) 
&serverAddr,sizeof(serverAddr)); 

これはC++である - クライアント

C++ - ServerはちょうどUDP-と同じである、C#の-clientにチャーアレイを転送 serialize-partのないクライアント。 ProtoException:ソースデータで 無効なフィールド:

は、私のようなエラーが出0

またはInvalideワイヤー型

編集: これは原始ファイル

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-File を作成し、そこからBuild libaryをProtoBuf.dllを参照して作成します をプリコンパイラで作成し、Unity3Dに含めるSerialize.dllを作成させます。

+0

実際にあなたの質問は何ですか? –

+0

が更新されました。質問は:なぜ私はこれらのエラーを取得するのですか?なぜそれは動作しません? :/ –

答えて

0

大丈夫です。私は答えを今見つけました。

Protobuf-Netは、Protobufの正確なバイトサイズではない場合、着信メッセージが固定長(私の場合は500)であれば本当の問題があります。

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

[OK]をクリックします。私は問題があなたがC#サーバを扱う方法に関連していると思う。私はあなたがこのアプローチを試みるべきだと思います:

MemoryStream stream = new MemoryStream(incoming、false);
ModelSerializerシリアライザ= new ModelSerializer(); message =(SendPack)serializer.Deserialize(ストリーム、受信、typeof(受信));

+0

これは私に与えます:InvalidCastException:ソースタイプから宛先タイプへキャストできません。 SendPackSerializer.Deserialize(Int32、System.Object、ProtoBuf.ProtoReader) –

+0

キャストエラー(私は変数を混乱させているかもしれません)のように聞こえ、Derializeの署名をチェックし、それに応じて変数を修正します。 – Robbykk

+0

すでに解決策が見つかりました。誰かが同じ問題を抱えている場合は、このスレッドに投稿してください –

関連する問題