zoukankan      html  css  js  c++  java
  • 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#学习-程序集和反射
    Unity学习-鼠标的常用操作(八)
    Unity学习-碰撞检测(七)
    Unity学习-摄像机的使用(六)
    Unity学习-地形的设置(五)
    Unity学习-预制(四)
    Unity学习-元素类型(三)
    Unity学习-软件的基本操作(二)
    Unity学习-工具准备(一)
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/7487867.html
Copyright © 2011-2022 走看看