1.    命名管道简介

"命名管道"或"命名管线"(Named Pipes)是一种简单的进程间通信(I P C)机制,Microsoft Windows NT,Windows 2000,Windows 95以及Windows 98均提供了对它的支持(但不包括Windows CE).命名管道可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支持可靠的,单向或双向的数据通信.用命名管道来设计应用程序实际非常简单,并不需要事先深入掌握基层网络传送协议(如T C P / I P或I P X)的知识.这是由于命名管道利用了微软网络提供者(M S N P)重定向器,通过一个网络,在各进程间建立通信.这样一来,应用程序便不必关心网络协议的细节.之所以要用命名管道作为自己的网络通信方案,一项重要的原因是它们充分利用了Windows NT及Windows 2000内建的安全特性.

2.命名管道作用

这里有一个可采纳命令管道的例子.假定我们要开发一个数据管理系统,只允许一个指定的用户组进行操作.想像在自己的办公室中,有一部计算机,其中保存着公司的秘密.我们要求只有公司的管理人员,才能访问及处理这些秘密.假定在自己的工作站机器上,公司内的每名员工都可看到网络上的这台计算机.然而,我们并不希望普通员工取得对机密材料的访问权.在这种情况下,命名管道可发挥出很好的作用,因为我们可开发一个服务器应用程序,令其以来自客户机的请求为准,对公司的秘密进行安全操作.服务器可将客户访问限制在管理人员身上,用Windows NT或新版Windows 2000自带的安全机制,便可非常轻松地做到这一点.在此要记住的一个重点是,将命名管道作为一种网络编程方案使用时,它实际上建立一个简单的客户机/服务器数据通信体系,可在其中可靠地传输数据.

3. 命名管道优点

使用比较方便,并且不需要声明端口号之类的,在程序中不需要关心权限之类的。

4. 命名管道限制(我个人认为)

管道只能一对一链接通信。

5. 命名管道实现

5.1 命名管道通讯辅助类

    /// <summary>

    /// pipe命名管道通讯辅助类

    /// </summary>

    public class StreamString

    {

        private Stream ioStream;

        private UnicodeEncoding streamEncoding;

        public StreamString(Stream ioStream)

        {

            this.ioStream = ioStream;

            streamEncoding = new UnicodeEncoding();

        }

        public string ReadString()

        {

            try

            {

                int len;

                len = ioStream.ReadByte() * ;

                len += ioStream.ReadByte();

                byte[] inBuffer = new byte[len];

                ioStream.Read(inBuffer, , len);

                return streamEncoding.GetString(inBuffer);

            }

            catch (Exception)

            {

                return null;

            }

        }

        public int WriteString(string outString)

        {

            byte[] outBuffer = streamEncoding.GetBytes(outString);

            int len = outBuffer.Length;

            if (len > UInt16.MaxValue)

            {

                len = (int)UInt16.MaxValue;

            }

            ioStream.WriteByte((byte)(len / ));

            ioStream.WriteByte((byte)(len & ));

            ioStream.Write(outBuffer, , len);

            ioStream.Flush();

            return outBuffer.Length + ;

        }

    }

    /// <summary>

    /// 自定义包装类

    /// </summary>

    public class StringToStream

    {

        private string Contents;

        private StreamString streamString;

        public StringToStream(StreamString ss, string contents)

        {

            Contents = contents;

            streamString = ss;

        }

        public void Start()

        {

            //string contents = File.ReadAllText(fn);

            streamString.WriteString(Contents);

        }

}

5.2 命名管道服务器端帮助类

public class PipeHelp

    { 

        private static int numThreads = ;

        /// <summary>

        /// 启动管道服通讯务器

        /// </summary>

        public static void PipeSeverSart()

        {

            try

            {

                int i;

                Thread[] servers = new Thread[numThreads];

                Console.WriteLine("Waiting for client connect...\n");

                for (i = ; i < numThreads; i++)

                {

                    servers[i] = new Thread(ServerThread);

                    servers[i].Start();

                }

            }

            catch (Exception)

            {

                throw new Exception("管道服务启动失败.");

                //PipeSeverSart();

            }

        }

        /// <summary>

        /// 退出管道。(程序退出时别忘了调用)

        /// </summary>

        public static void PipeSeverClose()

        {

            if (pipeServer != null)

            {

                try

                {

                    pipeServer.Disconnect();

                    pipeServer.Close();

                }

                catch (Exception exception)

                {

                    Console.WriteLine(exception.Message);

                }              

            } 

        }

        private static NamedPipeServerStream pipeServer;

        /// <summary>

        /// 处理函数

        /// </summary>

        /// <param name="data"></param>

        private static void ServerThread(object data)

        {

            try

            {

                Random reRandom = new Random();

                pipeServer =

                   new NamedPipeServerStream("VisualPlatformPipe", PipeDirection.InOut, numThreads);

                //int threadId = Thread.CurrentThread.ManagedThreadId;

                // Wait for a client to connect

                pipeServer.WaitForConnection();

                StreamString ss = new StreamString(pipeServer);

                //Console.WriteLine("Client connected on thread[{0}].", threadId);

                while (true)

                {

                    try

                    {

                        // Read the request from the client. Once the client has

                        // written to the pipe its security token will be available.

                        //ss.WriteString("I am the one true server!");

                        string temp = ss.ReadString();

                        if (temp != null)

                        {

                            if (temp.ToLower() == "close")//客户端通知服务器客户端退出

                            {

                                //为了客户端退出之后,可以再次连接到服务器端,重新设置一下服务i其管道

                                Close();

                                pipeServer = new NamedPipeServerStream("VisualPlatformPipe", PipeDirection.InOut, numThreads);

                                pipeServer.WaitForConnection();

                                ss = new StreamString(pipeServer);

                            }

                            else

                            {

                                StringToStream fileReader = new StringToStream(ss, SystemHelp.BusinessSystemID);

                                pipeServer.RunAsClient(fileReader.Start);

                            }

                        }

                        else////客户端未通知服务器客户端退出,客户端直接异常退出

                        {

                            Close();

                            pipeServer = new NamedPipeServerStream("VisualPlatformPipe", PipeDirection.InOut, numThreads);

                            pipeServer.WaitForConnection();

                            ss = new StreamString(pipeServer);

                        }

                    }

                    // Catch the IOException that is raised if the pipe is broken

                    // or disconnected.

                    catch (IOException e)

                    {

                        Console.WriteLine("ERROR: {0}", e.Message);

                    }

                }

            }

            catch (Exception)

            {

                 throw new Exception("管道服务启动失败.");

            }

        }

        /// <summary>

        /// 退出管道

        /// </summary>

        public static void Close()

        {

            if (pipeServer != null)

            {

                pipeServer.Disconnect();

                pipeServer.Close();

            }

        } 

    }

5.3客户端帮助类

   public class PipeClientHelp

    {

        private static StreamString m_StreamString = null;

        private static NamedPipeClientStream pipeClient = null;

        /// <summary>

        /// 启动客户端,连接服务器,只允许连接一次

        /// </summary>

        /// <returns></returns>

        public static bool StartConnection()

        {

            try

            {

                if (pipeClient == null)

                {

                    pipeClient =

                                    new NamedPipeClientStream(".", "VisualPlatformPipe",

                                        PipeDirection.InOut, PipeOptions.None,

                                        TokenImpersonationLevel.Impersonation);

                    pipeClient.Connect();

                    m_StreamString = new StreamString(pipeClient);

                }

            }

            catch (Exception exception)

            {

                pipeClient = null;

                throw new Exception("未启动服务器端" + exception.Message);

            }

            return true;

        }

        /// <summary>

        /// 通知服务器客户端即将退出

        /// </summary>

        public static void ClosePipe()

        {

            if (pipeClient != null)

            {

                m_StreamString.WriteString("close");

                m_StreamString = null;

                pipeClient.Close();

                pipeClient = null;

            }

        }

        /// <summary>

        /// 从服务器获取数据

        /// </summary>

        /// <returns></returns>

        public static string GetSystemID()

        {

            if (m_StreamString != null)

            {

                m_StreamString.WriteString("GetBusinessSystemId");

                return m_StreamString.ReadString();

            }

            return null;

        } 

    }

命名管道的C#实现的更多相关文章

  1. 使用命名管道的OVERLAPPED方式实现非阻塞模式编程 .

    命令管道是进程间通讯的一种常用方式,对于命令管道的介绍可以参考别的资料和书籍,这里推荐一个<VC++下命名管道编程的原理及实现>这篇博文,写得比较清楚.但是都是介绍了阻塞模式的编程,我这里 ...

  2. dotnet 替换 ASP.NET Core 的底层通讯为命名管道的 IPC 库

    这是一个用于本机多进程进行 IPC 通讯的库,此库的顶层 API 是采用 ASP.NET Core 的 MVC 框架,其底层通讯不是传统的走网络的方式,而是通过 dotnetCampus.Ipc 开源 ...

  3. C++和C#进程之间通过命名管道通信(上)

    C++和C#进程之间通过命名管道通信(上) "命名管道"是一种简单的进程间通信(IPC)机制.命名管道可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支 ...

  4. UWP使用命名管道与桌面程序通信 (C#)

    关于UWP的历史,其起源是Microsoft在Windows 8中引入的Metro apps.(后来又被称作Modern apps, Windows apps, Universal Windows A ...

  5. WCF全面解析学习(1)

    SOA的基本概念和设计思想 SOA并不是仅仅采用Web服务的架构,Web服务只是一种实现SOA的理想技术手段.SOA依赖于开放的标准.SOA的一个目标是让不同的厂商开发的服务能够相互操作. SOA支持 ...

  6. SQL Server 2008连接字符串写法大全

    一..NET Framework Data Provider for SQL Server 类型:.NET Framework类库使用:System.Data.SqlClient.SqlConnect ...

  7. windows系统下安装MySQL

    可以运行在本地windows版本的MySQL数据库程 序自从3.21版以后已经可以从MySQL AB公司获得,而且 MYSQL每日的下载百分比非常大.这部分描述在windows上安装MySQL的过程. ...

  8. MySQL配置文件改变了datadir值

    从Noinstall Zip Archive中安装MySQL正在从Noinstall软件包安装MySQL的用户可以使用这个说明来手动安装MySQL.从Zip archive 中安装MySQL的 步骤如 ...

  9. WCF开发指南之构建服务

    一. 引言 Windows通讯基础(简称为WCF)是一种SDK,用于让你使用典型的CLR编程结构(例如用于发布和消费服务的类和接口等)来构建Windows面向服务的应用程序.WCF的编程模型是声明性的 ...

随机推荐

  1. nopCommerce 3.9 大波浪系列 之 使用部署在Docker中的Redis缓存主从服务

    一.概述 nop支持Redis作为缓存,Redis出众的性能在企业中得到了广泛的应用.Redis支持主从复制,HA,集群. 一般来说,只有一台Redis是不可行的,原因如下: 单台Redis服务器会发 ...

  2. [TypeScript] Create a fluent API using TypeScript classes

    You can create an easy to chain API using TypeScript classes. Learn about the thisreturn type annota ...

  3. ssh连接上腾讯云、华为云Linux服务器,一会就自动断开

    客户端向服务端发送心跳 依赖 ssh 客户端定时发送心跳,putty.SecureCRT.XShell 都有这个功能. Linux / Unix 下,编辑 ssh 配置文件: # vim /etc/s ...

  4. T-SQL部分函数(转)

    函数类别 作用 聚合函数 执行的操作是将多个值合并为一个值.例如 COUNT.SUM.MIN 和 MAX. 配置函数 是一种标量函数,可返回有关配置设置的信息. 转换函数 将值从一种数据类型转换为另一 ...

  5. 新技能 get —— 五笔打字

    推荐一个图表记忆网站,五笔字根表图五笔字根表五笔输入法下载口诀五笔打字练习_查询: 1. 键盘的认识 键盘的版式就是那样设定的,主要是 26 个拉丁字母,分三排: QWERT(撇区), YUIOP(捺 ...

  6. Eclipse使用技巧总结(五)

    三十五.快速回退到上次编辑处 Ctrl + Q 三十六.查看调用层次 Ctrl + Alt + H 三十七.快速查看某个类 Ctrl + Shift + T 三十八.快速定位 Ctrl + K  :首 ...

  7. matlab 高阶(三)—— 插值(fft、)

    1. FFT 插值 y = interpft(x,n) y = [0, .5, 1., 1.5, 2., 1.5, 1., .5, 0, -.5, -1, -1.5, -2., -1.5, -1., ...

  8. WPF中取得预定义颜色

    原文:WPF中取得预定义颜色 使用XAML代码取得.net预定义颜色:<Page    xmlns="http://schemas.microsoft.com/winfx/2006/x ...

  9. 【狼窝乀野狼】Windows Server 2008 R 配置 Microsoft Server 2008 远程登录连接

    如果你已经了解了,或者你已经经历了,那么此篇文章对你是毫无用处.因为文笔深处未必有自己亲身体验来的真实有效. 闲话少说,直接上菜. 最近脑子“抽筋”,想安装一个服务器来玩玩,那么怎么选择呢?我的PC是 ...

  10. ASP.NET Core 新建项目 - macOS 环境 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 新建项目 - macOS 环境 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 新建项目 - macOS 环境 对于任何语言和 ...