Voy a leer los mensajes que se almacenan consecutivamente en el socket en el cliente C++ que se envían desde un servidor C#. Espero que pueda leer el tamaño de un mensaje así:protobuf: lea un mensaje en C++ desde C#
google::protobuf::uint32 m;
coded_input->ReadVarint32(&m);
cout << m << endl;
Entonces quiero leer el mensaje:
Person person;
CodedInputStream::Limit limit = coded_input->PushLimit(m);
person.ParseFromCodedStream(coded_input);
coded_input->PopLimit(limit);
el código C# parece:
var person = new Person { Id = 123456, Name = "Fred", Address = new Address { Line1 = "Flat 1", Line2 = "The Meadows ar garą " } };
Stream str = new NetworkStream(socket);
Serializer.SerializeWithLengthPrefix(str, person, PrefixStyle.Fixed32);
Se no funciona
me sale el error de C++ (43 es resultado de cout < < m < < endl;) (id, nombre, dirección son todos los campos en persona)
libprotobuf ERROR Google /protobuf/message_lite.cc:123] no se puede analizar el mensaje del tipo "Persona" porque falta campos obligatorios: ID, nombre, dirección
Cuando no leo la variante y analizo el mensaje directamente desde coded_input
, todo está bien (cuando cambio SerializeWithLengthPrefix
para serializar en el código del servidor). Sin embargo, necesito un método para distinguir los mensajes consecutivos, así que necesito saber el tamaño del mensaje que voy a leer. Simplemente no sé cómo enviar el tamaño.
I intentado:
Stream buf = new MemoryStream();
Serializer.Serialize(buf, person);
ProtoWriter writer = new ProtoWriter(str, null);
ProtoWriter.WriteInt32((int)buf.Length, writer);
pero entonces se obtiene:
Excepción no controlada: ProtoBuf.ProtoException: Invalid operación serialización con los de tipo alambre Ninguno en la posición 0 en protobuf. ProtoWriter.WriteInt32 (valor de Int32 , escritor de ProtoBuf.ProtoWriter) [0x00000] en: 0
en protobuftest.MainClass.Main (System.String [] args) [0x00097] en /home/lorddidger/studia/csharp/protobuf-test/protobuf-test/Main.cs:31
no soy capaz de enviar cualquier int de esa manera. ¿Qué está mal?
Actualización: En realidad, mi objetivo es encontrar una manera de transferir un número entero (tamaño) con protobuf. Necesito algún ejemplo (tanto C++ como C#) sobre cómo manejar eso porque no entiendo todos los detalles dentro de protobuf.
Me di cuenta de que SerializeWithLengthPrefix envía el prefijo (4 uint32) que se parece a: tamaño 0 0 0. El tamaño es el número de bytes del mensaje después de la serialización (supongo). ¡Pensé que PrefixStyle.Fixed32 dice que hay solo un uint32 antes del mensaje, pero hay 4!
Finalmente, pensé que debería usar ProtoWriter.WriteInt32 ((int) buf.Longitud, escritor) para transferir enteros porque seguí la sugerencia de somwhere in the internet que supongo que es una solución relevante para C++. Ahora veo que no debes escribir varints: están relacionados con el motor y es sofisticado para pasar el tiempo.
¿Debo enviar un mensaje con un int? ¿Cómo debería distinguir eso del próximo mensaje de que el tamaño está almacenado en el primero?
Veo que C# puede tener prefijos de hadle bien, pero ¿hay ALGÚN COMPATIBLE con C++ y C# manera de indicar el tamaño de un mensaje? De lo contrario, no hay ninguna forma de * * para poner en cola mensajes que me parezcan irracionales.
Awww Marc, son solo unos pocos miles de líneas de código ... ¿no te acuerdas? ;) – IAbstract
@IAbstract cómo * deseo * fueron solo unos pocos miles :) agregue en el modo de tiempo de ejecución, el compilador de IL completo, la implementación de v1, las diversas versiones de plataforma (CF, SL, WP7, Mono, etc.), el conjunto de pruebas original, el conjunto de pruebas del meta-modelo v2, el código-gen (.proto), las herramientas VS, ... Digamos que se suma :) –
Te cortaré un poco esta vez ... :) – IAbstract