zoukankan      html  css  js  c++  java
  • 命名管道的C#实现

    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() * 256;
    
                    len += ioStream.ReadByte();
    
                    byte[] inBuffer = new byte[len];
    
                    ioStream.Read(inBuffer, 0, 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 / 256));
    
                ioStream.WriteByte((byte)(len & 255));
    
                ioStream.Write(outBuffer, 0, len);
    
                ioStream.Flush();
    
     
    
                return outBuffer.Length + 2;
    
            }
    
        }
    
     
    
        /// <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 = 1;
    
            /// <summary>
    
            /// 启动管道服通讯务器
    
            /// </summary>
    
            public static void PipeSeverSart()
    
            {
    
                try
    
                {
    
                    int i;
    
                    Thread[] servers = new Thread[numThreads];
    
                    Console.WriteLine("Waiting for client connect...
    ");
    
                    for (i = 0; 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(100);
    
                        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;
    
            } 
    
        }
  • 相关阅读:
    片段
    告诉长夜
    明天
    开源一个WEB版本GEF,基于SVG的网页流程图框架
    RCP:ISourceLocator翻译
    SVG:textPath深入理解
    SVG:linearGradient渐变在直线上失效的问题解决方案
    【半平面交】BZOJ2618[Cqoi2006]凸多边形
    【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖
    【凸包+旋转卡壳】平面最远点对
  • 原文地址:https://www.cnblogs.com/shanranlei/p/3629901.html
Copyright © 2011-2022 走看看