4

我有一个 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 );
        }
    }
}
4

2 回答 2

3

大多数用任何语言编写的程序都可以通过套接字进行通信。因此,C# 套接字侦听器可以侦听 C++ 发送者。他们通过交换一系列字节来做到这一点(非常简化)

您在这里所做的是使用字节数组中的MsgPack序列化 C# 对象并将其发送过来。另一方面,相同的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;
    }

根据您的操作系统.. C++ 中的 sizeof(int) 将为 4 个字节(字符)。C# 中的 sizeof(int) 也是 4 个字节。

因此,理论上您可以通过 C++ 和 C# 程序之间的套接字连接交换 12 ( 4 * 3 )个字节,以便双方的天气对象几乎相同

于 2011-11-10T00:25:40.117 回答
1

在 C++ 中,您应该使用 MSGPACK_DEFINE 宏,因为您正在处理用户定义的类。MSGPACK 网站上的 C++ 快速入门中对此进行了全部说明。

为了使它起作用,您必须确保对象中每个属性的类型在不同语言中对应。这正是 MSGPACK 的意图,我自己使用它来编写基于包含 MSGPACK 对象有效负载的 ZeroMQ 消息的 SQLITE 服务器。最初我使用 JSON 对象作为消息正文,但后来我想以 gzip 格式发送一个属性,并且在 MSGPACK 中交换比尝试处理 JSON 字符串中的二进制数据更容易。

您可能想阅读http://wiki.msgpack.org/display/MSGPACK/Design+of+Serialization以了解它是如何工作的。从概念上讲,这就像将 000A00130002 转换为“10,19,2”然后再转换回来。当然,MSGPACK 不使用字符串作为序列化格式,而是使用一种非常有效的与语言无关的二进制格式。

于 2011-11-11T07:03:01.807 回答