- PR -

IPC チャネルを使用したプロセス間通信について

1
投稿者投稿内容
ani
常連さん
会議室デビュー日: 2007/05/17
投稿数: 44
投稿日時: 2008-03-10 19:11
こんにちは。
いつもお世話になっております。

Windows アプリケーションで IPC チャネルを使用したプロセス間通信を実装しようとしています。
(以下のサイトなどを参考にしました。)
http://d.hatena.ne.jp/PoohKid/20071226/ipc
http://d.hatena.ne.jp/tetsuarossa/20070325/p1
http://tryhost.net/~catwalk/?diary%2F2007%2F07%2F04

以下のようなコード(サーバー、クライアント、IPC オブジェクト)を記述したのですが、
クライアントで IPCData オブジェクトの Status プロパティが「1」になりません。

コード:

//サーバー ( C# )
class Program
{
static void Main(string[] args)
{

IpcServerChannel serverChannel = new IpcServerChannel("remote");
ChannelServices.RegisterChannel(serverChannel, true);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(IPCData), "IPCData", WellKnownObjectMode.Singleton);

IPCData ipcd = new IPCData();
ipcd.Status = 1;


Console.ReadLine();
}
}


'クライアント ( VB )
Public Class Form1

Private timer As Timer

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim iPCClientChannel As New IpcClientChannel()
ChannelServices.RegisterChannel(iPCClientChannel, True)
RemotingConfiguration.RegisterWellKnownClientType(GetType(IPCData), "ipc://remote/IPCData")

Dim timerDelegate As TimerCallback = New TimerCallback(AddressOf MyClock)
timer = New Timer(timerDelegate, Nothing, 0, 1000)

End Sub

Private Sub MyClock(ByVal o As Object)
Dim ipcd As New IPCData()
Console.WriteLine("Status : {0}", ipcd.Status)

End Sub

End Class


//IPC オブジェクト ( C# )
public class IPCData : MarshalByRefObject
{

private int _Status;

public int Status
{
get
{
return _Status;
}
set
{
_Status = value;
}
}

}



私の認識では、IPC チャネルを使用したプロセス間通信とは、サーバー、クライアントで設定した値を
それぞれで共有できるというものなのですが、そもそもそれが間違っているのでしょうか?
それとも記述の方法が間違っているのでしょうか?

ご存知の方が見えましたらご教示下さい。

<環境>
Windows XP, .NET Framework 2.0, Visual Studio 2005, C#, VB

[ メッセージ編集済み 編集者: ani 編集日時 2008-03-11 09:12 ]
Azulean
大ベテラン
会議室デビュー日: 2008/01/04
投稿数: 123
お住まい・勤務地: 大阪府
投稿日時: 2008-03-11 00:02
クライアント側は何をやっているのか分かりません。

・サーバーと同期を取るオブジェクトは、挙げられたサイトいずれもActivator.GetObjectで取得していますが、そのコードがありません。
・IPCClientというクラスは何者ですか?
・サーバとクライアント共に"同じ型"が必要です。C#とVBでそれぞれで型を定義した場合は別の型になります。
(同じアセンブリの同じ型をサーバー・クライアント共に使える状態にしなければならない)

MSDNにもサンプルらしいのがあるようですが、動作確認はしていません。
http://msdn2.microsoft.com/ja-jp/library/xcs3s8f3(VS.80).aspx
ani
常連さん
会議室デビュー日: 2007/05/17
投稿数: 44
投稿日時: 2008-03-11 09:25
Azuleanさん、レスありがとうございます。

引用:

クライアント側は何をやっているのか分かりません。


クライアント側では1秒間隔のスレッドタイマーで Status を出力する処理をしています。
今回のプロセス間通信とは直接関係はありません。
紛らわしいコードを記述して申し訳ありません。

引用:

・サーバーと同期を取るオブジェクトは、挙げられたサイトいずれもActivator.GetObjectで取得していますが、そのコードがありません。


すみません。一つ参考サイトが抜けていました。
http://msdn2.microsoft.com/ja-jp/library/system.runtime.remoting.channels.ipc.ipcclientchannel(VS.80).aspx
MSDN の IpcClientChannel クラスを使用するコード例を参考に記述しました。( C# )
確かに最初に挙げたサイトでは Activator.GetObject を使用していますね。
MSDN の記述は違う用途で使用するものなのでしょうか?

引用:

・IPCClientというクラスは何者ですか?
・サーバとクライアント共に"同じ型"が必要です。C#とVBでそれぞれで型を定義した場合は別の型になります。
(同じアセンブリの同じ型をサーバー・クライアント共に使える状態にしなければならない)


IPCClient は IPCData の間違いでした。(修正しました。)
ani
常連さん
会議室デビュー日: 2007/05/17
投稿数: 44
投稿日時: 2008-03-11 11:26
解決しました。

引用:

私の認識では、IPC チャネルを使用したプロセス間通信とは、サーバー、クライアントで設定した値を
それぞれで共有できるというものなのですが、そもそもそれが間違っているのでしょうか?


どうやらこの認識が誤っているようです。
サーバーはクライアント同士のメッセージ要求を処理するために立てるのですね。
というわけで、クライアント2を追加した以下のコードを記述しました。

コード:

//サーバー ( C# )
class Program
{
   static void Main(string[] args)
   {

      IpcServerChannel serverChannel = new IpcServerChannel("remote");
      ChannelServices.RegisterChannel(serverChannel, true);
      RemotingConfiguration.RegisterWellKnownServiceType(typeof(IPCData), "IPCData", WellKnownObjectMode.Singleton);

      Console.ReadLine();

   }
}


'クライアント1 ( VB )
Public Class Form1
   Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

      Dim iPCClientChannel As New IpcClientChannel()
      ChannelServices.RegisterChannel(iPCClientChannel, True)
      RemotingConfiguration.RegisterWellKnownClientType(GetType(IPCData), "ipc://remote/IPCData")

      Dim ipcd As New IPCData()        
      Console.WriteLine("Status : {0}", ipcd.Status)

   End Sub
End Class


'クライアント2 ( VB )
Public Class Form2
   Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

      Dim iPCClientChannel As New IpcClientChannel()
      ChannelServices.RegisterChannel(iPCClientChannel, True)
      RemotingConfiguration.RegisterWellKnownClientType(GetType(IPCData), "ipc://remote/IPCData")

      Dim ipcd As New IPCData()        
      ipcd.Status = 1

   End Sub
End Class


//IPC オブジェクト ( C# )
public class IPCData : MarshalByRefObject
{
   private int _Status;
   public int Status
   {
      get
      { 
         return _Status;
      }
      set
      {
         _Status = value;
      }
   }
}




サーバー、クライアント2、クライアント1の順で起動すると、
Status プロパティが「1」として表示されました。

どうもお騒がせしました。
1

スキルアップ/キャリアアップ(JOB@IT)