2009-08-25 1 views
1

、クライアントは次の処理を行い受信側ではtemp(byte [])をSTRUCTなどに変換してメンバーcCommandとsPatameterにアクセスできるようにする必要がありますが、この時点でどのように手がかりを取る必要はありませんか...リアリティー構造体である必要はありません、私はちょうどデータ自体を抽出する必要があります。[C#の]私は、サーバー(C#の)にクライアント(C++)からデータを転送するために、名前付きパイプを使用しています

注 - STRUCT MESSAGEは私が思いついたものです。つまり、異なるフォーマットが再構成に役立つ(例えばsParameterの長さを追加するとどうなるでしょうか?)、COMMANDとPARAMETERが必要です1つのブロックで(可能な場合)転送されます。

要件は単純である: は - COMMANDアクションは 実行する必要があるかを示す固定長の8文字列である - パラメータが可変長であり、各コマンドに依存するパラメータ(これは問題を生じない限り)

例えば

: COMMAND = TRANS

PARAMETER = C:\ file.txtをC:\新規フォルダ\ FILE.TXT

(これは単に例示するためであり、多くのアプリケーションがある)

可能であれば、私はそれをデータのまとまり(byte [])として抽出し、それを分解することができる自分のアプリケーションに渡したいと思います。サイズの読み込みのファンではなく、次にフィールド私のコミュニケーションが私の実装に過度にリンクされていることを必要とするフィールドです。

この転送を実装するより適切な方法がある場合は、私に教えてください...アドバイスは歓迎されるでしょう... 助けが大いに評価されるでしょう。 ありがとう、

答えて

1

あなたは、構造体の定義を持っている場合C++では、それをC#で定義することができます(少し細かくする必要があります)。ソケットのサイズを読み取ってMarshal.PtrToStructureを使用して、C#定義された構造体にマーシャリングします。

/* Define you structure like this (possibly) */ 
struct MESSAGE 
{ 
    [MarshalAs(UnmanageType.ByValArray, SizeConst=8)] 
    byte[] cCommand; 
    [MarshalAs(UnmanagedType.LPStr)] 
    string sParameter; 
}; 

/* Read data into an instance of MESSAGE like this */ 
byte[] bytes = new byte[Marshal.SizeOf(MESSAGE)]; 

socket.Receive(bytes, 0, bytes.Length); 
IntPtr ptr = Marshal.AllocHGlobal(bytes.Length); 

try 
{ 
    Marshal.Copy(bytes, 0, ptr, bytes.Length); 
    m = (MESSAGE)Marshal.PtrToStructure(ptr, typeof(MESSAGE)); 
} 
finally 
{ 
    Marshal.FreeHGlobal(ptr); 
} 
+0

これは可変長文字列(sParameter)でも同様ですか? – Shaitan00

+1

MESSAGE構造体に別のMarshalAs属性を追加しましたが、動作するはずです。 – scottm

+0

あなたの専門家の意見では - これは良い方法ですか?私が言及したように、私はそれが良い選択だと思ったのでSTRUCTを作成しました - しかし、私の問題を解決する良い方法があるなら私はすべての耳です... – Shaitan00

1

プラットフォーム間でデータを渡すための提案 - 自分でシリアライズ/デシリアライズを行わないでください。 GoogleのProtocol Buffersのような図書館は、より安全な賭けになるでしょう。

EDIT:効率的なオーバーザワイヤ表現が重要でない場合、(C#とC++のためのJsonCppのために例えばJson.NET)JSONを使用するためにもっと簡単だろう

+2

質問をC#としてタグ付けされているので、ここでの.NET実装のためのリンクです:http://code.google.com/p/protobuf-net/とのhttp:/ /code.google.com/p/protobuf-csharp-port/ –

+0

は、元のC++アプリケーションが何かをシリアル化しているようには聞こえません。ソケットにバイト配列を送信するだけです。プロトコルバッファはすばらしいツールですが、私はこれがこのようなことに対して少し残忍であると思います。 – scottm

+0

scottm、それは8文字+文字列インスタンスを送信しているようですが、構造体のバイトをコピーするとほとんど確実に失敗します。シリアル化はここで重要だと思います。 – orip

0

NamedPipeClientStream/NamedPipeServerStreamクラスが何をやっている簡素化すべきストリームとして名前付きパイプへのアクセスを公開する.NETフレームワークであります。

データを渡すための簡単な解決策は、ラインベースのプロトコルを使用することです。 1行=パラメータを持つ一つのコマンド:

using (NamedPipeClientStream pipeClient = 
     new NamedPipeClientStream(".", "testpipe", PipeDirection.In)) 
{ 
    pipeClient.Connect(); 

    using (StreamReader sr = new StreamReader(pipeClient)) 
    { 
     string command; 
     while ((command = sr.ReadLine()) != null) 
     { 
      Console.WriteLine("Received command: {0}", command); 
     } 
    } 
} 
+0

これは、私が想像する.NET 3.5(System.Pipes)でのみサポートされています。古いP/Invokeで2.0を使用しています...古い学校のC++で送信者を思い出しました – Shaitan00

+0

'hPipeInst'を' System .IO.Stream'はほとんど同じ利点を与えます(例えば、あなたのために 'OverlappedPtr'の全てを行います)。そして、送信側では、パイプに改行を終えた文字列を書くだけで、必ずしも構造体である必要はありません。 – dtb

+0

そして、COMMANDとPARAMETERの間に区切り記号を使用しますか?私は両方の部分を抽出できるようにする必要があります(私はパラメータを使って何をすべきかを理解するためにコマンドをオンに切り替えます)。 – Shaitan00

関連する問題