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;
    }

OSによって異なりますが、C ++のsizeof(int)は4バイト(chars)になります。C#のsizeof(int)も4バイトです。

したがって、理論的には、C ++プログラムとC#プログラムの間のソケット接続を介して12 (4 * 3)バイトを交換できるため、天気オブジェクトは両側でほぼ同じになります。

于 2011-11-10T00:25:40.117 に答える
1

C ++では、ユーザー定義クラスを処理しているため、MSGPACK_DEFINEマクロを使用する必要があります。これはすべて、MSGPACKWebサイトのC++クイックスタートで説明されています。

これを機能させるには、オブジェクトの各属性のタイプが言語間で対応していることを確認する必要があります。これはまさにMSGPACKが意図したことであり、私はそれを使用して、MSGPACKオブジェクトペイロードを含むZeroMQメッセージに基づいてSQLITEサーバーを作成しました。元々、メッセージ本文にJSONオブジェクトを使用していましたが、1つの属性をgzipで送信したかったので、JSON文字列でバイナリデータを処理するよりもMSGPACKで交換する方が簡単でした。

http://wiki.msgpack.org/display/MSGPACK/Design+of+Serializationを読んで、それがどのように機能するかを理解することをお勧めします。概念的には、000A00130002を「10,19,2」に変換して元に戻すようなものです。もちろん、MSGPACKはシリアル化形式として文字列を使用しませんが、代わりに言語に依存しない非常に効率的なバイナリ形式を使用します。

于 2011-11-11T07:03:01.807 に答える