1. 程式人生 > >c# IPC實現本機進程之間的通信

c# IPC實現本機進程之間的通信

config aps gis UC service remote .get 分布 onf

原文:c# IPC實現本機進程之間的通信

  IPC可以實現本地進程之間通信。這種用法不是太常見,常見的替代方案是使用wcf,remoting,web service,socket(tcp/pipe/...)等其他分布式部署方案來替代進程之間的通信。雖然不常見但也避免不了一些場景會使用該方案。

  應用包含:

1)使用IPC技術實現多client與一個sever通信(不過是本機,感覺意義不大,但如果想實現本機上運行確實是一個不錯的方案);

2)使用IPC技術實現訂閱者和生產者分離時,一個server接收並消費消息,客戶端是生產消息的。

技術分享圖片
  1 1:新建一個MessageObject類庫
2 3 代碼如下: 4 5 using System; 6 using System.Collections.Generic; 7 8 namespace MessageObject 9 { 10 //MarshalByRefObject 允許在支持遠程處理的應用程序中跨應用程序域邊界訪問對象。 11 public class RemoteObject : MarshalByRefObject 12 { 13 public static Queue<string> qMessage { get
; set; } //使用消息隊列儲存消息 14 15 public string SendMessage(string message) 16 { 17 if (qMessage == null) 18 { 19 qMessage = new Queue<string>(); 20 } 21 qMessage.Enqueue(message); 22 23 return
message; 24 } 25 } 26 } 27 2:新建一個控制臺程序,名稱:IPCServer,是IPC的服務端 28 using System; 29 using System.Runtime.Remoting.Channels.Ipc; 30 using System.Runtime.Remoting.Channels; 31 using System.Runtime.Remoting; 32 using MessageObject; 33 using System.Threading; 34 using System.Collections.Generic; 35 36 namespace IPCServer 37 { 38 /// <summary> 39 /// IPC Server 40 /// </summary> 41 class Program 42 { 43 static void Main(string[] args) 44 { 45 StartServer(); 46 47 Thread t = new Thread(new ThreadStart(ReceviceMessage)); //使用線程獲取消息 48 t.Start(); 49 } 50 private static void StartServer() 51 { 52 IpcServerChannel channel = new IpcServerChannel("ServerChannel"); 53 ChannelServices.RegisterChannel(channel, false); 54 RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject), "RemoteObject", WellKnownObjectMode.SingleCall); 55 Console.WriteLine("message server running..."); 56 } 57 private static void ReceviceMessage() 58 { 59 while (true) 60 { 61 Queue<string> qMessage = RemoteObject.qMessage; 62 if (qMessage != null) 63 { 64 if (qMessage.Count > 0) 65 { 66 string message = qMessage.Dequeue(); 67 Console.WriteLine("recevice message is:" message); 68 } 69 } 70 Thread.Sleep(1000); //每一秒獲取一次 71 } 72 } 73 74 } 75 } 76 3:新建一個控制臺程序,名稱:IPCClient,IPC客戶端 77 代碼如下: 78 using System; 79 using MessageObject; 80 using System.Runtime.Remoting.Channels.Ipc; 81 using System.Runtime.Remoting.Channels; 82 83 namespace IPCClient 84 { 85 class Program 86 { 87 static void Main(string[] args) 88 { 89 RemoteObject objRemoteObject = ConnectServer(); 90 Send(objRemoteObject); 91 } 92 private static void Send(RemoteObject objRemoteObject) 93 { 94 while (true) 95 { 96 Console.WriteLine("please input message..."); 97 string message = Console.ReadLine(); 98 try 99 { 100 objRemoteObject.SendMessage(message); 101 Console.WriteLine("send success"); 102 } 103 catch (System.Runtime.Remoting.RemotingException) 104 { 105 Console.WriteLine("can not connect message server"); 106 } 107 } 108 } 109 private static RemoteObject ConnectServer() 110 { 111 IpcClientChannel channel = new IpcClientChannel(); 112 ChannelServices.RegisterChannel(channel, false); 113 RemoteObject objRemoteObject = (RemoteObject)Activator.GetObject(typeof(RemoteObject), "ipc://ServerChannel/RemoteObject"); 114 return objRemoteObject; 115 } 116 } 117 }
View Code

  使用技巧:

1)使用之間必須定義好一個進程之間通信的對象(該對象繼承了MarshalByRefObject ,允許在支持遠程處理的應用程序中跨應用程序域邊界訪問對象);

 1     public class MyProcessSendObject : MarshalByRefObject
 2     {
 3         private string taskInfo = string.Empty;
 4 
 5         public void Add(string taskInfo)
 6         {
 7             Console.WriteLine("Add:{0}", taskInfo);
 8             this.taskInfo = taskInfo;
 9         }
10 
11         public string GetTask()
12         {
13             Console.WriteLine("GetTask:{0}", taskInfo);
14             return taskInfo;
15         }
16 
17     }

2)服務端是發布了一個IPC服務,供客戶端段來綁定使用;

 1         //I PC(inter process communication)的功能可以實現同一臺機器上的不同進程間通信。
 2         static void Main(string[] args)
 3         {
 4             Console.WriteLine("I‘m server......");
 5             //Instantiate our server channel.
 6             IpcChannel serverchannel = new IpcChannel("testchannel");
 7             //Register the server channel.
 8             ChannelServices.RegisterChannel(serverchannel, false);
 9             //Register this service type.
10             RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyProcessSendObject), "myObj", WellKnownObjectMode.Singleton);

13 Console.WriteLine("press Enter to exit"); 14 Console.ReadLine(); 15 Console.WriteLine("server stopped"); 16 }

3)客戶端使用時需要綁定服務端發布的地址,之後獲取發布的對象(暫時可以這麽理解:數據的傳遞和同步是通過對象序列化、反序列化),在客戶端操作該對象時實際上是操作了服務端的對象。

 1         static void Main(string[] args)
 2         {
 3             Console.WriteLine("I‘m client......");
 4             IpcChannel tcc = new IpcChannel();
 5             ChannelServices.RegisterChannel(tcc, false);
 6 
 7             MyProcessSendObject myObj = (MyProcessSendObject)Activator.GetObject(typeof(MyProcessSendObject), "ipc://testchannel/myObj");
 8             
 9             Console.WriteLine("client send myvalue start");
10             myObj.Add("Task 1");
11             myObj.GetTask();
12             myObj.Add("Task 2");
13             myObj.GetTask();
14             Console.WriteLine("client send myvalue complete");
15             Console.ReadLine();
16         }

工程結構:

技術分享圖片

測試:

技術分享圖片

c# IPC實現本機進程之間的通信