您现在的位置是:首页 > 文章详情

c# IPC实现本机进程之间的通信

日期:2018-05-04点击:376
原文: 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 }

工程结构:

测试:

 

原文链接:https://yq.aliyun.com/articles/678809
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章