当前位置: 首页 > news >正文

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

原文: 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         }

工程结构:

测试:

 

相关文章:

  • 网络编程--基础TCP
  • 使用jMeter构造大量并发HTTP请求进行微服务性能测试
  • DAY18-Django之分页和中间件
  • jmeter接口测试步骤
  • 网关地址设置
  • [mvc] 简单的forms认证
  • nmap 端口扫描工具
  • NGINX发布支持动态配置的开源Web服务器
  • Java List集合
  • C++11 lambda表达式与函数对象
  • 人人都能学会的python编程教程8:条件判断与循环
  • #考研#计算机文化知识1(局域网及网络互联)
  • homebridge安装问题解决
  • DesignPattern(三)结构型模式(上)
  • 八周一次课 10.23 linux任务计划cron 10.24 chkconfig工具 10.25 systemd管理服务 10.26 unit介绍 10.27 target介绍...
  • php的引用
  • @jsonView过滤属性
  • 07.Android之多媒体问题
  • create-react-app项目添加less配置
  • Django 博客开发教程 16 - 统计文章阅读量
  • ES6系列(二)变量的解构赋值
  • ES6系统学习----从Apollo Client看解构赋值
  • input的行数自动增减
  • Java超时控制的实现
  • leetcode46 Permutation 排列组合
  • Median of Two Sorted Arrays
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • PHP 7 修改了什么呢 -- 2
  • React16时代,该用什么姿势写 React ?
  • spring + angular 实现导出excel
  • Vue 重置组件到初始状态
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 前端面试总结(at, md)
  • 微信支付JSAPI,实测!终极方案
  • 一天一个设计模式之JS实现——适配器模式
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • 我们雇佣了一只大猴子...
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​secrets --- 生成管理密码的安全随机数​
  • #define与typedef区别
  • (动态规划)5. 最长回文子串 java解决
  • (转)h264中avc和flv数据的解析
  • (转)Unity3DUnity3D在android下调试
  • (转载)(官方)UE4--图像编程----着色器开发
  • .bat批处理(六):替换字符串中匹配的子串
  • .net Application的目录
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .Net 代码性能 - (1)
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .Net程序帮助文档制作
  • .NET运行机制
  • /*在DataTable中更新、删除数据*/