dot net core 使用 IPC 进程通信

标签: dnc 进程通信 IPC C# pipe
68人阅读 评论(0) 收藏 举报
分类:

本文告诉大家如何使用dot net core 和其他进程进行通信


一般都是使用 WCF 或 remoting 做远程通信,但是 dot net core 不支持 WCF 所以暂时我就只能使用 管道通信。

原理

管道通信使用的是 Pipe 需要启动一对才可以

在 NamedPipeServerStream 启动之后可以接受其他 NamedPipeClientStream 连接。

因为现在已经使用了 await 了,所以建议全部都可以写异步。

创建的 NamedPipeServerStream 需要告诉管道的命名,和通信方式,通信可以分为单向和双向,大家使用枚举去看一下就可以知道。

            var pipe = new NamedPipeServerStream("lindexi", PipeDirection.InOut);

上面代码就创建了一个管道,之后需要等待有连接才可以发送数据。

            await pipe.WaitForConnectionAsync();

等待了连接之后,就可以发送数据

            string str = "发送消息";

            var spxnfSrxldhhv = Encoding.UTF8.GetBytes(str);

            pipe.Write(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);

注意,需要指定发送数据的长度和数据,通过这个方法发送是不建议的。

如果需要使用一个比较高级的方法传输,请看文章最后

这时另一个程序就需要下面代码连接

            var pipe = new NamedPipeClientStream(".", "lindexi", PipeDirection.InOut, PipeOptions.None);

            pipe.Connect()

上面代码使用的 NamedPipeClientStream 需要指定管道的命名才可以找到。

连接之后可以通过这个方式读取数据

            var spxnfSrxldhhv = new byte[65535];

            var n = pipe.Read(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);

            var str = Encoding.UTF8.GetString(spxnfSrxldhhv, 0, n);

对于读写数据很多时候就使用 pipe 的读写,写入字节,读出字节。

因为一次读取可能会卡很多时间,所以建议使用异步读。

如果觉得每次发送都需要转 byte 然后进行写,代码很多,可以使用下面的代码

            var stream = new StreamWriter(pipe);

            stream.Write("发送消息");

            stream.Flush();

注意不要使用下面的代码

            using (var stream = new StreamWriter(pipe))
            {
                stream.Write("发送消息");
            }

原因是 using 会关闭 pipe 所以使用之后就不能在写。

例子

首先创建两个程序,一个是 WPF 程序 DgvlzKixtdin ,另一个是 dot net core 控制台 HclkvyDanuiag 。接着需要从 DgvlzKixtdin 发送数据,从 HclkvyDanuiag 接收数据。

在 WPF 程序添加一个 TextBlock 和 Button ,点击 Button 就发送消息到 dot net core 程序。收到消息就在 TextBlock 显示。

在 Button 点击的代码写下面代码

      private async void HixKkikjgp_OnClick(object sender, RoutedEventArgs e)
        {
            var pipe = new NamedPipeServerStream("lindexi", PipeDirection.InOut);

            await pipe.WaitForConnectionAsync();

            string str = "发送消息";

            var spxnfSrxldhhv = Encoding.UTF8.GetBytes(str);

            pipe.Write(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);

            spxnfSrxldhhv = new byte[100];
            var n = pipe.Read(spxnfSrxldhhv, 0, 100);

            str = Encoding.UTF8.GetString(spxnfSrxldhhv, 0, n);

            TjdsguhmKzj.Text = str;
        }

然后在 dot net core 程序写下面代码

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var pipe = new NamedPipeClientStream(".", "lindexi", PipeDirection.InOut, PipeOptions.None);

            pipe.Connect();

            var spxnfSrxldhhv = new byte[65535];

            var n = pipe.Read(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);

            var str = Encoding.UTF8.GetString(spxnfSrxldhhv, 0, n);

            Console.WriteLine(str);

            str = "收到";

            spxnfSrxldhhv = Encoding.UTF8.GetBytes(str);

            pipe.Write(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);

            Console.Read();
        }

先启动 WPF 程序,然后启动控制台

这时点击按钮之后就打开控制台可以看到控制台可以收到消息

然后 WPF 也收到控制台发过来的消息

序列化

虽然使用StreamWriter可以减少写入读取的代码,但是实际上这样只能用来传字符串,需要把类传输还是比较难,所以我找到了 Protobuf ,使用这个库可以简单使用。

首先打开 Nuget 安装 Protobuf 第一个

我这里使用 protobuf-net

然后创建一个类用来传输

    [ProtoContract]
    public class TyfxxTlkbjn
    {
        public string DczSwdsun { get; set; }
    }

使用下面代码可以进行写入

Serializer.Serialize(pipe, 实例);

所以修改一下上面的按钮按下

        {
            var pipe = new NamedPipeServerStream("lindexi", PipeDirection.InOut);

            await pipe.WaitForConnectionAsync();

            var tyfxxTlkbjn = new TyfxxTlkbjn()
            {
                DczSwdsun = "发送消息"
            };

            Serializer.Serialize(pipe, tyfxxTlkbjn);

            pipe.Disconnect();

修改 dot net core的代码

        static void Main(string[] args)
        {
            var pipe = new NamedPipeClientStream(".", "lindexi", PipeDirection.InOut, PipeOptions.None);

            pipe.Connect();

            var tyfxxTlkbjn = Serializer.Deserialize<TyfxxTlkbjn>(pipe);

            Console.WriteLine(tyfxxTlkbjn.DczSwdsun);

            Console.Read();
        }

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

查看评论

Android 之 IPC 进程通信全解析

Android 之 IPC 进程通信全解析本篇博客的框架什么是IPCIPC(Inter-Process Communication) 进程间通信,是指两个不同进程之间数据交换的过程。在明确其之前,需要...
  • lisdye2
  • lisdye2
  • 2016-06-28 14:39:13
  • 4552

DotNet or Java

           一切都乱了。         北京来的所谓的“高参”,叫嚣:Java比DotNet好,Windows是最烂的操作系统、未来互联网的网速会达到200MB/S、大城市的网吧未来都会直...
  • juejue1984
  • juejue1984
  • 2006-11-21 18:07:00
  • 795

进程间通信(IPC)之消息队列

漫谈进程间通信之消息队列,进程通信家族中不可或缺的一员。交流学习,共同进步。...
  • Xiao__Tian__
  • Xiao__Tian__
  • 2016-07-07 01:24:58
  • 4188

进程间通信 IPC、LPC、RPC

原文请见:进程间通信IPC、LPC、RPC进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法。进程是计算机系统分配资源的...
  • lanchunhui
  • lanchunhui
  • 2016-03-14 12:54:33
  • 989

C# IPC 之 Socket 进程间通信 源码

  • 2010年03月01日 17:23
  • 90KB
  • 下载

linux下进程间通信IPC几种方式性能比较

在项目中,经常会遇到单机上进程间的通信,常用的进程间通信方式一般有以下几种 1 socket  2 unixsocket 3 共享内存(share-memory) 4 管道(pipe) 5 消息队列(...
  • zhiyuan_2007
  • zhiyuan_2007
  • 2014-09-24 16:57:19
  • 4766

【二】 Chrome的进程间通信

1. Chrome进程通信的基本模式     进程间通信,叫做IPC(Inter-Process Communication)。Chrome最主要有三类进程,一类是Browser主进程,我们一直尊称它...
  • QHH_QHH
  • QHH_QHH
  • 2015-10-12 18:02:20
  • 1577

进程间通信(IPC):消息队列(Message Queue)

消息队列与命名管道有许多相似之处,但少了在打开和关闭管道方面的复杂性。与命名管道相比,消息队列的优势在于,它独立于发送和接收进程而存在。 消息队列函数的定义如下所示: #include in...
  • lijiajia81
  • lijiajia81
  • 2013-01-26 14:18:52
  • 2831

linux基础——linux进程间通信(IPC)机制总结

在linux下的多个进程间的通信机制叫做IPC(Inter-Process Communication),它是多个进程之间相互沟通的一种方法。在linux下有多种进程间通信的方法:半双工管道、命名管道...
  • a987073381
  • a987073381
  • 2016-07-23 21:33:12
  • 9116

DotNet访问Oracle

方法一:通过System.Data.OracleClient(需要安装Oracle客户端并配置tnsnames.ora)string strcnn = "User ID=lportal;Passwor...
  • zlz_212
  • zlz_212
  • 2007-08-01 20:34:00
  • 2285
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 70万+
    积分: 9963
    排名: 2185
    博客专栏
    文章分类
    最新评论