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. ios开发事件处理之 四:hittest方法的底层实现与应用

    #import "XMGWindow.h" /** 1:注意点:hitTest方法内部会调用pointInside方法,询问触摸点是否在自己身上,当遍历子控件时,传入的坐标点要进行 ...

  2. 微信开发学习日记(七):开源微商城wemall

    最近嘛,不是在调研PHP和微信的行情么. 发现,微商城是非常火爆的一个领域,既然业务有搞头,那么技术这一块也有很多选择. 网上发现了wemall这个开源的PHP实现的微商城. 下载了开源版本,PHP后 ...

  3. [RxJSv& Javascript] forkJoin (reactive Promise.all) & Map

    forkJoin: When all observables complete emit the last value from each. productMap: Map<number, IP ...

  4. JBoss AS 7之初步了解(The Return Of The King)

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvam9obl9mX2xhdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  5. poj1007——DNA Sorting

    Description One measure of ``unsortedness'' in a sequence is the number of pairs of entries that are ...

  6. NOIP 模拟 路径求和 - Tarjan+dfs+码

    题目大意: 各一个奇环内向森林,求每两个点对间的距离之和.无法到达则距离为-1. 分析: 首先Tarjan找出size大于1的连通分量(环),环中的边的贡献可以单独计算. 然后从入度为0的点向内dfs ...

  7. Android Studio 如何打JAR包(修订版)

    AndroidStudio项目打包成jar 前言:在eclipse中我们知道如何将一个项目导出为jar包,现在普遍AndroidStuido开发,这里一步一步详加介绍AS项目打包成jar,jar和ar ...

  8. Apache POI Word基本使用

    Apache POI Word 1.什么是Apache POI? Apache POI是一个流行的API,使用Java程序创建,修改和显示MS-Office文件. 它是由Apache Software ...

  9. QT5.5.1 为Qtcreator 编译的程序添加管理员权限

    QT版本:5.5.1 QT Creator QT Creator 编译出来的程默认是不带管理员权限的.有时是需要管理员权限. 第一步: 创建文件 uac.manifest 添加如下代码 <?xm ...

  10. 反编译Jar包

    Jar 包(Java Archive)是对 Java 程序的打包,它可能包含源码,也可能没有. 对于有包含源码的 Jar 包,在 Eclipse 工程里设定好 source code 路径后能直接查看 ...