命名管道的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() * ; 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#实现的更多相关文章
- 使用命名管道的OVERLAPPED方式实现非阻塞模式编程 .
命令管道是进程间通讯的一种常用方式,对于命令管道的介绍可以参考别的资料和书籍,这里推荐一个<VC++下命名管道编程的原理及实现>这篇博文,写得比较清楚.但是都是介绍了阻塞模式的编程,我这里 ...
- dotnet 替换 ASP.NET Core 的底层通讯为命名管道的 IPC 库
这是一个用于本机多进程进行 IPC 通讯的库,此库的顶层 API 是采用 ASP.NET Core 的 MVC 框架,其底层通讯不是传统的走网络的方式,而是通过 dotnetCampus.Ipc 开源 ...
- C++和C#进程之间通过命名管道通信(上)
C++和C#进程之间通过命名管道通信(上) "命名管道"是一种简单的进程间通信(IPC)机制.命名管道可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支 ...
- UWP使用命名管道与桌面程序通信 (C#)
关于UWP的历史,其起源是Microsoft在Windows 8中引入的Metro apps.(后来又被称作Modern apps, Windows apps, Universal Windows A ...
- WCF全面解析学习(1)
SOA的基本概念和设计思想 SOA并不是仅仅采用Web服务的架构,Web服务只是一种实现SOA的理想技术手段.SOA依赖于开放的标准.SOA的一个目标是让不同的厂商开发的服务能够相互操作. SOA支持 ...
- SQL Server 2008连接字符串写法大全
一..NET Framework Data Provider for SQL Server 类型:.NET Framework类库使用:System.Data.SqlClient.SqlConnect ...
- windows系统下安装MySQL
可以运行在本地windows版本的MySQL数据库程 序自从3.21版以后已经可以从MySQL AB公司获得,而且 MYSQL每日的下载百分比非常大.这部分描述在windows上安装MySQL的过程. ...
- MySQL配置文件改变了datadir值
从Noinstall Zip Archive中安装MySQL正在从Noinstall软件包安装MySQL的用户可以使用这个说明来手动安装MySQL.从Zip archive 中安装MySQL的 步骤如 ...
- WCF开发指南之构建服务
一. 引言 Windows通讯基础(简称为WCF)是一种SDK,用于让你使用典型的CLR编程结构(例如用于发布和消费服务的类和接口等)来构建Windows面向服务的应用程序.WCF的编程模型是声明性的 ...
随机推荐
- C语言数据类型取值范围解析
版权声明:本文为博主原创文章,未经博主允许不得转载. 为什么int类型的取值范围会是-2^31 ~ 2^31-1 ,为什么要减一呢? 计算机里规定,8位二进制为一个字节,拿byte来说,一个BY ...
- Spark源代码阅读笔记之DiskStore
Spark源代码阅读笔记之DiskStore BlockManager底层通过BlockStore来对数据进行实际的存储.BlockStore是一个抽象类,有三种实现:DiskStore(磁盘级别的持 ...
- [tmux] Organize your terminal using tmux panes
Learn to organize your workspace using tmux. We'll create a new tmux session and learn how to create ...
- 数组filter方法对数组元素进行过滤
Array.prototype.filter对数组中元素进行过滤 /** * @method reduce * @param {number} item 当前迭代的数组元素 * @param {num ...
- scala 加载与保存xml文档
package scala_enhance.xml import scala.xml.XML import scala.io.Source import jdk.internal.org.xml.sa ...
- 记录一次对接XX支付SDK过程中报错问题
我们支付平台以前我不做对接上游的,偶然间替别人做"对接了XX支付的相关接口的工作".在工作过程中发现SDK和对外提供服务过程中很容易出问题.在此做个记录,为了以后相关工作中作为自己 ...
- Popup 解决位置不随窗口/元素FrameworkElement 移动更新的问题
原文:Popup 解决位置不随窗口/元素FrameworkElement 移动更新的问题 Popup弹出后,因业务需求设置了StaysOpen=true后,移动窗口位置或者改变窗口大小,Popup的位 ...
- MVVM初步搭建应用
MVVM模式:利用 prism Microsoft.Practices.Prism.dllWPF Interaction框架简介 添加Interactions库的引用.主要添加如下两个DLL: Mic ...
- ART、JIT、AOT、Dalvik之间有什么关系?
JIT与Dalvik JIT是"Just In Time Compiler"的缩写,就是"即时编译技术",与Dalvik虚拟机相关. 怎么理解这句话呢?这要从A ...
- 5.1 入门整合案例(SpringBoot+Spring-data-elasticsearch) ---- good
本节讲解SpringBoot与Spring-data-elasticsearch整合的入门案例. 一.环境搭建 新建maven项目,名字随意 pom.xml <parent> <gr ...