命名管道的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的编程模型是声明性的 ...
随机推荐
- nopCommerce 3.9 大波浪系列 之 使用部署在Docker中的Redis缓存主从服务
一.概述 nop支持Redis作为缓存,Redis出众的性能在企业中得到了广泛的应用.Redis支持主从复制,HA,集群. 一般来说,只有一台Redis是不可行的,原因如下: 单台Redis服务器会发 ...
- [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 ...
- ssh连接上腾讯云、华为云Linux服务器,一会就自动断开
客户端向服务端发送心跳 依赖 ssh 客户端定时发送心跳,putty.SecureCRT.XShell 都有这个功能. Linux / Unix 下,编辑 ssh 配置文件: # vim /etc/s ...
- T-SQL部分函数(转)
函数类别 作用 聚合函数 执行的操作是将多个值合并为一个值.例如 COUNT.SUM.MIN 和 MAX. 配置函数 是一种标量函数,可返回有关配置设置的信息. 转换函数 将值从一种数据类型转换为另一 ...
- 新技能 get —— 五笔打字
推荐一个图表记忆网站,五笔字根表图五笔字根表五笔输入法下载口诀五笔打字练习_查询: 1. 键盘的认识 键盘的版式就是那样设定的,主要是 26 个拉丁字母,分三排: QWERT(撇区), YUIOP(捺 ...
- Eclipse使用技巧总结(五)
三十五.快速回退到上次编辑处 Ctrl + Q 三十六.查看调用层次 Ctrl + Alt + H 三十七.快速查看某个类 Ctrl + Shift + T 三十八.快速定位 Ctrl + K :首 ...
- 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., ...
- WPF中取得预定义颜色
原文:WPF中取得预定义颜色 使用XAML代码取得.net预定义颜色:<Page xmlns="http://schemas.microsoft.com/winfx/2006/x ...
- 【狼窝乀野狼】Windows Server 2008 R 配置 Microsoft Server 2008 远程登录连接
如果你已经了解了,或者你已经经历了,那么此篇文章对你是毫无用处.因为文笔深处未必有自己亲身体验来的真实有效. 闲话少说,直接上菜. 最近脑子“抽筋”,想安装一个服务器来玩玩,那么怎么选择呢?我的PC是 ...
- ASP.NET Core 新建项目 - macOS 环境 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 新建项目 - macOS 环境 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 新建项目 - macOS 环境 对于任何语言和 ...