1

私は C# と C++ の間でさまざまな成功を収めて通信しようとしています。

リプライ/リクエストを使用して 2 つの間でメッセージを送信できますが、受信している double が正しくありません。

デバッグの目的と理解のために、私は現在以下を実行しています:

Clrzmq 3.0 rc1、Google ProtocolBuffer 2.5、Protobuf-csharp-port-2.4、ZeroMQ-3.2.3

.プロト

package InternalComm;

message Point 
{
    optional double x = 1;
    optional double y = 2;
    optional string label = 3;
}

server.cpp (該当部分)

while (true) {
    zmq::message_t request;

    // Wait for next request from client
    socket.recv (&request);
    zmq::message_t reply (request.size());
    memcpy ((void*)reply.data(), request.data(), request.size());
    socket.send(reply);
}

client.cs (該当部分)

public static Point ProtobufPoint(Point point)
    {
        Point rtn = new Point(0,0);
        using (var context = ZmqContext.Create())
        {
            using (ZmqSocket requester = context.CreateSocket(SocketType.REQ))
            {
                requester.Connect("tcp://localhost:5555");
                var p = InternalComm.Point.CreateBuilder().SetX(point.X).SetY(point.Y).Build().ToByteArray();

                requester.Send(p);

                string reply = requester.Receive(Encoding.ASCII);
                Console.WriteLine("Input: {0}", point);

                byte[] bytes = System.Text.Encoding.ASCII.GetBytes(reply);
                var message = InternalComm.Point.ParseFrom(bytes);
                rtn.X = message.X;
                rtn.Y = message.Y;

                Console.WriteLine("Output: {0}", rtn);
            }
        }
        return rtn;
    }

C# 側では、Point は非常に単純な構造体です。x および y プロパティのみ。

上記のコードを実行した結果、単体テストから得られた結果は次のとおりです。

入力 (1.31616874365468、4.55516872325469)
出力 (0.000473917985115791、4.55516872323627)

入力 (274.120398471829、274.128936418736)
出力 (274.077917334613、274.128936049925)

入力 (150.123798461987、2.345E-12)
出力 (145.976459594794、1.11014954927532E-13)

入力 (150, 0)
出力 (145.96875, 0)

問題は、protobuf コードが正しくないことだと考えています (これは Skeet 側のバグであるとは思えません)。また、server.cpp はメッセージに対して何もせず、そのまま返すという前提で実行しています。

考え?

4

2 に答える 2

4

なぜ ASCII --> バイト --> 解析ステップなのですか? バイトを解析している場合は、バイトを読み取る必要があります。テキストを解析している場合は、それを読む必要があります。

不要な文字セット変換は、誤りである可能性が非常に高いようです。

于 2013-07-15T03:54:45.467 に答える
4

このrequestor.Receive(Encoding.ASCII)呼び出しは、バイトのブロックではなく、文字列を受け取るように設計されています。メッセージを ASCII 文字列として返すようにインスタンスに要求しているZmqSocketため、コンテンツが変更される可能性が非常に高くなります。バイト配列を送信している場合は、バイト配列を受信します。

これを試して:

int readSize;
byte[] reply = requester.Receive(null, out readSize);
var message = InternalComm.Point.ParseFrom(reply);

変数には、受信したブロック内の実際の有効なバイト数が含まれます。readSizeこれは、配列のサイズによって異なる場合replyがあるため、配列をスライスして、ProtoBuf に適したものにする必要がある場合があります。

于 2013-07-15T05:52:57.837 に答える