Может ли msgpack упаковать определенный пользователем объект в C #, отправить пакет в приложение C ++, где он затем распаковывается? - PullRequest
3 голосов
/ 10 ноября 2011

У меня есть сервер ответов C #, который может упаковать объект и отправить его клиенту C # запрашивающей стороны. Могу ли я сделать то же самое, но с сервером ответов C #, взаимодействующим с клиентом-запросчиком C ++?

Вот пример моего сервера ответов C #:

using System;
using System.Text;
using ZMQ;
using MsgPack;

namespace zmqMpRep
{
    public class Weather
    {
        public int zipcode;
        public int temperature;
        public int humidity;
    }
    public class zmqMpRep
    {
        public static void Main(string[] args)
        {

            Socket replier  = new Socket( SocketType.REP );
            replier.Bind( "tcp://127.0.0.1:9293" );
            while( true ) {
                Weather weather = new Weather { zipcode = 60645, temperature = 67, humidity = 50 };
                CompiledPacker packer   = new CompiledPacker( false );
                byte[] packWeather  = packer.Pack<Weather> ( weather );
                string request  = replier.Recv(Encoding.Unicode);
                Console.WriteLine( request.ToString() );
                replier.Send( packWeather );
                Weather test    = packer.Unpack<Weather>( packWeather );
                Console.WriteLine( "The temp of zip {0} is {1}", test.zipcode, test.temperature );
            }
        }
    }
}

Вот мой клиент C # запроса:

using System;
using System.Text;
using ZMQ;
using MsgPack;

namespace zmqMpReq
{
    public class Weather
    {
        public int zipcode;
        public int temperature;
        public int humidity;
    }
    public class zmqMpReq
    {
        public static void Main(string[] args)
        {
            CompiledPacker packer   = new CompiledPacker( false );
            Socket requester        = new Socket( SocketType.REQ );
            requester.Connect( "tcp://127.0.0.1:9293" );
            string request          = "Hello";
            requester.Send( request, Encoding.Unicode );
            byte[] reply            = null;
            try {
                reply        = requester.Recv();
            }
            catch( ZMQ.Exception e) {
                Console.WriteLine( "Exception: {0}", e.Message );
            }
            Weather weather     = packer.Unpack<Weather>( reply );
            Console.WriteLine( "The temp of zip {0} is {1}", weather.zipcode, weather.temperature );
            System.Threading.Thread.Sleep( 5000 );
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 10 ноября 2011

Большинство программ, написанных на любом языке, могут общаться через сокеты. Таким образом, слушатель сокета C # может слушать отправителя C ++. Они делают, заменяя последовательность байтов (очень упрощенно)

То, что вы делаете здесь, это сериализация объекта C # с использованием MsgPack в байтовом массиве и его отправка. На другом конце тот же MsgPack используется для десериализации объекта C #.

Это не будет работать на всех языках программирования, если ваша библиотека сериализации / десериализации не поддерживает это, что в вашем случае MsgPack не поддерживает.

Возьми этот класс C #

public class Weather
{
    public int zipcode;
    public int temperature;
    public int humidity;
}

Эквивалент класса C ++

  class Weather
    {
    public:
       int zipcode;
       int temperature;
       int humidity;
    }

В зависимости от вашей ОС .. sizeof (int) в C ++ будет 4 байта (символа). sizeof (int) в C # также составляет 4 байта.

Таким образом, теоретически вы можете обмениваться 12 (4 * 3) байтами по сокетному соединению между программами на C ++ и C #, так что объект погоды с обеих сторон будет примерно одинаковым

1 голос
/ 11 ноября 2011

В C ++ вы должны использовать макрос MSGPACK_DEFINE, потому что вы имеете дело с определяемым пользователем классом.Все это объясняется в кратком обзоре C ++ на веб-сайте MSGPACK.

Чтобы это работало, вы должны убедиться, что типы каждого атрибута в вашем объекте соответствуют языкам.Это именно то, для чего предназначался MSGPACK, и я сам использовал его для написания сервера SQLITE на основе сообщений ZeroMQ, содержащих полезную нагрузку объекта MSGPACK.Первоначально я использовал объект JSON для тел сообщений, но затем я хотел отправить один атрибут в формате gzip, и было проще заменить MSGPACK, чем пытаться работать с двоичными данными в строке JSON.

Вы можетехочу прочитать http://wiki.msgpack.org/display/MSGPACK/Design+of+Serialization, чтобы понять, как это работает.Концептуально это похоже на преобразование 000A00130002 в «10,19,2» и обратно.Конечно, MSGPACK не использует строки в качестве формата сериализации, но вместо этого использует очень эффективный двоичный формат, который не зависит от языка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...