C # protobuf Deserialize Fehler bei ZMQ, ungültiger Schreibtyp

stimmen
1

Ich habe zwei Programm. mit Server DiscoverServerMessage erstellen und sie durch protobuf serialisiert und es durch ZMQ senden. In Client-Seite deserialisieren Nachricht aber Fehler:

Ivalid wire-type; this usually means you have over-written a file without truncating or setting the length.

Ich habe unten Klasse in DLL-Projekt.

[ProtoContract]
public class DiscoverServerMessage 
{
    [ProtoMember(1)]
    public int Port { get; set; }
    [ProtoMember(2)]
    public string IP { get; set; }
    [ProtoMember(3)]
    public string ServerName { get; set; }
    public DiscoverServerMessage() { }
}

In Project Server haben diesen Code:

public class Server
{
    static void Main(string[] args)
    {
        ZContext ctx = new ZContext();
        ZSocket broadcastSrocket = new ZSocket(ctx, ZSocketType.PUB);
        broadcastSrocket.Connect(tcp://127.0.0.1:2666);
        ZFrame zfr;
        DiscoverServerMessage message = new DiscoverServerMessage() { Port = 2667 , ServerName = My };
        message.IP = 127.0.0.1;
        using (MemoryStream str = new MemoryStream())
        {
            Serializer.SerializeWithLengthPrefix(str,message,PrefixStyle.Fixed32);
            zfr = new ZFrame(str.ToArray());
        }
        broadcastSrocket.Send(zfr);
    }
}

Im Client-Programm:

public class Server
{
    static void Main(string[] args)
    {
        ZContext ctx = new ZContext();
        ZSocket subSocket = new ZSocket(ctx, ZSocketType.SUB);
        subSocket.Connect(tcp://127.0.0.1:2666);
        subSocket.SubscribeAll();
        ZError err;
        ZFrame zfr = subSocket.ReceiveFrame(out err);
        DiscoverServerMessage message;
        using (MemoryStream stream = new MemoryStream(zfr.Read()))
        {
            message = Serializer.DeserializeWithLengthPrefix<DiscoverServerMessage >(stream,PrefixStyle.Fixed32);
        }
    }
}

was ist mein Fehler?

Veröffentlicht am 18/12/2018 um 11:11
quelle vom benutzer
In anderen Sprachen...                            


1 antworten

stimmen
0

Das erste , was zu tun ist , vergessen , um die Serialisierung seits und einfach zu prüfen , ob , was Sie war schicken , was Sie erhalten, so - eine Kopie erhalten , was auch immer str.ToArray()ist (Server) und vergleichen Sie es mit , was auch immer zfr.Read()ist (Client). Wenn die zwei Nutzlasten nicht identisch sind: alle anderen Wetten ab . Der einfachste Weg , dies zu tun , ist in der Regel über hex, so:

(Server):

byte[] blob = str.ToArray();
string hex = BitConverter.ToString(blob); // <== get a copy of this somehow
zfr = new ZFrame(blob);
...

(Klient)

byte[] blob = zfr.Read();
string hex = BitConverter.ToString(blob); // <== get a copy of this somehow
using (MemoryStream stream = new MemoryStream(blob))
...

und nur überprüfen: Sind die beiden Hex-Sequenzen identisch?

Hinweis: Da Sie ein Rahmenprotokoll (mit ZFrame), können Sie nicht wirklich benötigen , um die Länge Präfix hier , aber ... es sollte nicht schaden. Es sieht aus wie Sie an jedem Ende hier entsprechenden Code verwenden - und die (von Ihrem Code beeinflusst) folgendes funktioniert:

static class Program
{
    static void Main()
    {
        byte[] blob;

        // taken from server code
        using (MemoryStream str = new MemoryStream())
        {
            DiscoverServerMessage message = new DiscoverServerMessage() { Port = 2667, ServerName = "My" };
            message.IP = "127.0.0.1";

            Serializer.SerializeWithLengthPrefix(str, message, PrefixStyle.Fixed32);
            blob = str.ToArray();
        }
        System.Console.WriteLine(BitConverter.ToString(blob));

        // taken from client code
        using (MemoryStream stream = new MemoryStream(blob))
        {
            DiscoverServerMessage message;
            message = Serializer.DeserializeWithLengthPrefix<DiscoverServerMessage>(stream, PrefixStyle.Fixed32);
            Console.WriteLine(message.Port);
            Console.WriteLine(message.ServerName);
            Console.WriteLine(message.IP);
        }

    }
}

Der Ausgang ist hier:

12-00-00-00-08-EB-14-12-09-31-32-37-2E-30-2E-30-2E-31-1A-02-4D-79
2667
My
127.0.0.1

Wenn wir die gleiche Sache nur mit tun Serialize/ Deserialize(keine Länge-Präfix), so erhalten wir (vorhersagbar):

08-EB-14-12-09-31-32-37-2E-30-2E-30-2E-31-1A-02-4D-79
2667
My
127.0.0.1

Also es sollte funktionieren entweder mit oder ohne die längen Präfix, solange der Client und Server übereinstimmen (was sie scheinen in Ihrem Code).

Beantwortet am 18/12/2018 um 16:52
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more