C# 使用命名管道进行网络进程间通信

目录

写在前面

代码实现

服务端代码

客户端代码

调用示例


写在前面

使用 NamedPipeServerStream 和 NamedPipeClientStream 类,实现命名管道方式的网络通讯,支持跨网络和多个服务器实例的全双工通信、基于消息的通信以及客户端模拟;需要特别说明的是TokenImpersonationLevel 的四个枚举项,对应了 SecurityAnonymous、SecurityIdentification、SecurityImpersonation和SecurityDelegation,分别代表如下四种模拟的等级。

  • 匿名(Anonymous):无法获取有关客户端的标识信息,且无法模拟客户端;
  • 识别(Identification):可以获取有关客户端的信息(如安全标识符和特权),但是无法模拟客户端;
  • 模拟(Impersonation):可以在本地模拟客户端的安全上下文。,但无法在远程系统上模拟客户端;
  • 委托(Delegation):可以在本地和远程系统上模拟客户端的安全上下文。

不同的模拟等级具有不同的权限,当权限足够时服务端才能响应对应级别的操作请求。

代码实现

服务端代码

using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;public class PipeServer
{private static int numThreads = 4;private static string token = "天王盖地虎,今晚打老虎";public static void Main(){int i;Thread?[] servers = new Thread[numThreads];Console.WriteLine("\n*** Named pipe server stream with impersonation example ***\n");Console.WriteLine("Waiting for client connect...\n");for (i = 0; i < numThreads; i++){servers[i] = new Thread(ServerThread);servers[i]?.Start();}Thread.Sleep(250);while (i > 0){for (int j = 0; j < numThreads; j++){if (servers[j] != null){if (servers[j]!.Join(250)){Console.WriteLine("Server thread[{0}] finished.", servers[j]!.ManagedThreadId);servers[j] = null;i--;    // decrement the thread watch count}}}}Console.WriteLine("\nServer threads exhausted, exiting.");}private static void ServerThread(object? data){var pipeServer = new NamedPipeServerStream("test.named.pipe", PipeDirection.InOut, numThreads);var threadId = Thread.CurrentThread.ManagedThreadId;// Wait for a client to connectpipeServer.WaitForConnection();Console.WriteLine("Client connected on thread[{0}].", threadId);try{// Read the request from the client. Once the client has// written to the pipe its security token will be available.StreamString ss = new StreamString(pipeServer);// Verify our identity to the connected client using a// string that the client anticipates.ss.WriteString(token); //对暗号string filename = ss.ReadString();// Read in the contents of the file while impersonating the client.ReadFileToStream fileReader = new ReadFileToStream(ss, filename);// Display the name of the user we are impersonating.Console.WriteLine("Reading file: {0} on thread[{1}] as user: {2}.",filename, threadId, pipeServer.GetImpersonationUserName());pipeServer.RunAsClient(fileReader.Start);}// Catch the IOException that is raised if the pipe is broken// or disconnected.catch (IOException e){Console.WriteLine("ERROR: {0}", e.Message);}pipeServer.Close();}
}// Defines the data protocol for reading and writing strings on our stream
public class StreamString
{private Stream ioStream;private UnicodeEncoding streamEncoding;public StreamString(Stream ioStream){this.ioStream = ioStream;streamEncoding = new UnicodeEncoding();}public string ReadString(){int len = ioStream.ReadByte() * 256;len += ioStream.ReadByte();byte[] inBuffer = new byte[len];ioStream.Read(inBuffer, 0, len);return streamEncoding.GetString(inBuffer);}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();// 加上了包头,就是上面写入的定义内容长度的两个字节,所以长度加2return outBuffer.Length + 2;}
}// Contains the method executed in the context of the impersonated user
public class ReadFileToStream
{private string fn;private StreamString ss;public ReadFileToStream(StreamString str, string filename){fn = filename;ss = str;}public void Start(){string contents = File.ReadAllText(fn);ss.WriteString(contents);}
}

客户端代码

using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Security.Principal;
using System.Text;
using System.Threading;public class PipeClient
{private static int numClients = 4;private static string token = "天王盖地虎,今晚打老虎";public static void Main(string[] args){if (args.Length > 0){if (args[0] == "spawnclient"){var pipeClient = new NamedPipeClientStream("127.0.0.1", "test.named.pipe",PipeDirection.InOut, PipeOptions.None,TokenImpersonationLevel.Impersonation);Console.WriteLine("Connecting to server...\n");pipeClient.Connect();var ss = new StreamString(pipeClient);// Validate the server's signature string.if (ss.ReadString() == token) //对暗号{// The client security token is sent with the first write.// Send the name of the file whose contents are returned// by the server.ss.WriteString("E:\\projects\\test_response.txt");// Print the file to the screen.Console.Write(ss.ReadString());}else{Console.WriteLine("Server could not be verified.");}pipeClient.Close();// Give the client process some time to display results before exiting.Thread.Sleep(4000);Console.ReadLine();}}else{Console.WriteLine("\n*** Named pipe client stream with impersonation example ***\n");StartClients();}}// Helper function to create pipe client processesprivate static void StartClients(){string currentProcessName = Environment.CommandLine;// Remove extra characters when launched from Visual StudiocurrentProcessName = currentProcessName.Trim('"', ' ');currentProcessName = Path.ChangeExtension(currentProcessName, ".exe");Process?[] plist = new Process?[numClients];Console.WriteLine("Spawning client processes...\n");if (currentProcessName.Contains(Environment.CurrentDirectory)){currentProcessName = currentProcessName.Replace(Environment.CurrentDirectory, String.Empty);}// Remove extra characters when launched from Visual StudiocurrentProcessName = currentProcessName.Replace("\\", String.Empty);currentProcessName = currentProcessName.Replace("\"", String.Empty);int i;for (i = 0; i < numClients; i++){// Start 'this' program but spawn a named pipe client.plist[i] = Process.Start(currentProcessName, "spawnclient");}while (i > 0){for (int j = 0; j < numClients; j++){if (plist[j] != null){if (plist[j]!.HasExited){Console.WriteLine($"Client process[{plist[j]?.Id}] has exited.");plist[j] = null;i--;    // decrement the process watch count}else{Thread.Sleep(250);}}}}Console.WriteLine("\nClient processes finished, exiting.");}
}// Defines the data protocol for reading and writing strings on our stream.
public class StreamString
{private Stream ioStream;private UnicodeEncoding streamEncoding;public StreamString(Stream ioStream){this.ioStream = ioStream;streamEncoding = new UnicodeEncoding();}public string ReadString(){int len = ioStream.ReadByte() * 256;len += ioStream.ReadByte();var inBuffer = new byte[len];ioStream.Read(inBuffer, 0, len);return streamEncoding.GetString(inBuffer);}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; // 加上了包头,就是上面写入的定义内容长度的两个字节,所以长度加2}
}

调用示例

服务端控制台输出: 

 客户端控制台输出:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/601004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python使用zdppy_crud框架快速生成基本增删改查接口

概述 zdppy_amcrud这个框架的强大之处在于只需要几行代码&#xff0c;就可以拥有新增、修改、删除、批量删除、查询、查询所有等常见的接口。 本教程中&#xff0c;我们来演示一下基本的用法。 创建数据库和表 首先&#xff0c;我们需要提前准备好数据库和表&#xff0c;便…

【STM32】STM32学习笔记-ADC模数转换器(21)

00. 目录 文章目录 00. 目录01. ADC简介02. ADC主要特征03. 逐次逼近型ADC04. ADC功能描述05. ADC基本结构06. 输入通道07. 转换模式08. 触发控制09. 数据对齐10. 转换时间11. 校准12. 硬件电路13. 附录 01. ADC简介 小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F1…

基于JavaWeb+SSM+Vue基于微信小程序的消防隐患在线举报系统的设计与实现

基于JavaWebSSMVue基于微信小程序的消防隐患在线举报系统的设计与实现 源码获取入口KaiTi 报告Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 KaiTi 报告 1.1 题目背景 随着信息化飞速发展&#xff0c;互联网不…

【Python】Excel不同sheet另存为不同CSV

我有一个excel&#xff0c;内有不同sheet&#xff0c;现在批量生成不通csv文件&#xff0c;并以sheet名命名&#xff0c;或根据sheet名调整命名。 # 读取新的Excel文件 df pd.read_excel(rD:\itm\data.xlsx, sheet_nameNone)# 遍历每个sheet&#xff0c;将其另存为不同的CSV文…

基于单片机的护理床控制器设计

一、摘要 随着科技的不断发展&#xff0c;人们对生活质量的要求越来越高&#xff0c;特别是在医疗保健领域。护理床作为医院病房中常见的设备&#xff0c;其功能和性能直接影响到患者的康复进程。本文主要介绍了一种基于单片机的护理床控制器设计&#xff0c;该控制器可以实现…

Go语言增量式学习1

Go语言增量式学习1 Go语言增量式学习1&#xff0c; 又名&#xff1a;Go企业级应用到底层开发&#xff08;第1天&#xff09; PS:这个系列是准备做从go基础到Web开发&#xff0c;系统编程&#xff0c;云原生应用, 网络编程, 工具和脚本开发, 机器学习&#xff0c;Cgo编程&…

本地计算机 上的 My5OL808 服务启动后停止,某些服务在未由其他服务或程序使用时将自动停止

客户反馈说mysql启动不了&#xff0c;报错信息&#xff1a; 本地计算机 上的 My5OL808 服务启动后停止&#xff0c;某些服务在未由其他服务或程序使用时将自动停止。 查了不少资料&#xff0c;最后分析问题是这样的&#xff0c;手动或者重复安装mysql时&#xff0c;创建了多个…

C#,归并排序算法(Merge Sort Algorithm)的源代码及数据可视化

归并排序 归并算法采用非常经典的分治策略&#xff0c;每次把序列分成n/2的长度&#xff0c;将问题分解成小问题&#xff0c;由复杂变简单。 因为使用了递归算法&#xff0c;不能用于大数据的排序。 核心代码&#xff1a; using System; using System.Text; using System.Co…

蓝桥杯-双指针 | 最长连续不重复子序列 | 算法基础

⭐简单说两句⭐ ✨ 正在努力的小新~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &…

Nodejs+express后端学习笔记(1)

1 Node.js安装 1、下载安装包&#xff1a;进入官网&#xff08;https://nodejs.org/en&#xff09;&#xff0c;下载左侧的稳定版。 2、选择安装位置&#xff0c;不用勾选自动安装必要工具。 其他都默认Next。 配置环境&#xff0c;具体参考本文章&#xff1a; https://blo…

智能风扇控制系统设计与实现

一、摘要 随着科技的不断发展&#xff0c;人们对生活质量的要求越来越高&#xff0c;特别是在家居环境方面。智能风扇控制系统作为智能家居的重要组成部分&#xff0c;可以为用户提供更加舒适、便捷的生活体验。本文主要介绍了一种基于单片机的智能风扇控制系统设计与实现方法…

WPF 怎么判断MediaElement视频播放完成

WPF MediaElement控件中没有属性可以直接判断视频是否被播放完了&#xff0c;那要怎么判断视频是否播放完成呢&#xff1f; 其实我们可以使用订阅MediaEnded事件&#xff0c;当视频播放完后&#xff0c;会触发该事件。 MediaElement.MediaEnded Event&#xff1a;在媒体结束时发…

提升网络安全重要要素IP地址

在数字化时代&#xff0c;网络安全已经成为人们关注的焦点。本文将深入探讨网络安全与IP地址之间的紧密联系&#xff0c;以及IP地址在构建数字世界的前沿堡垒中的关键作用。 网络安全是当今数字社会中不可忽视的挑战之一。而IP地址&#xff0c;作为互联网通信的基础协议&#…

数据结构 —— 手写排序算法

数据结构 —— 手写排序算法 一、堆排序二、快速排序 能手撸堆排序和快速排序&#xff0c;相信你在面试中已经能应付大部分排序问题了。 一、堆排序 建堆算法在面试中非常常见&#xff0c;我曾经就遇到过。因此为避免踩坑&#xff0c;特此开记录帖。堆必须是一棵完全二叉树&a…

Allegro如何进行四层板板层设计

Allegro如何进行四层板板层设计 板层设计说明 在进行多层板设计时我们画好PCB板框后&#xff0c;都要进行板层的设计。这里就以最简单的4层板为例为大家举例说明。 板层设置 点击“Setup”->“Cross Section Editor”如下图所示&#xff1a; 也可以直接点击工具栏进入…

java基于ssm框架的校园闲置物品交易平台论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本校园闲置物品交易平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

LeetCode-Z 字形变换(6)

题目描述&#xff1a; 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1a; P A H N A P L S I I G Y I R 之后&#xff0c;你的输出需要从左往…

安防监控EasyCVR视频融合/汇聚平台大华热成像摄像机智能告警上报配置步骤

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

python实现圆圈烟花_附完整源码【第21篇—python过新年】

文章目录 前言效果图&#xff08;动态&#xff09;完整代码代码讲解总结寄语 前言 烟花是一种庆祝、欢庆或庆典活动中常见的美丽表现&#xff0c;它们以多彩的光芒和炫丽的形状为人们带来欢乐和惊喜。在这个项目中&#xff0c;我们将使用Python编程语言创建一个简单而有趣的程…

Pytest的测试报告——Allure

一、html-report测试报告 html-report测试报告。是pytest下基本的测试报告。要使用pytest-html测试报告&#xff0c;就要确保python版本在3.6及以上即可。本身pytest所提供的测试结果汇总&#xff0c;是基于控制台的文本输出形式。 pytest-html是基于HTML格式实现的测试报告的…