当前位置: 首页 > news >正文

【微软技术栈】C#.NET 中的管道操作

C#.NET 管道为进程间通信提供了平台。 管道分为两种类型:

  • 匿名管道。

    匿名管道在本地计算机上提供进程间通信。 与命名管道相比,虽然匿名管道需要的开销更少,但提供的服务有限。 匿名管道是单向的,不能通过网络使用。 仅支持一个服务器实例。 匿名管道可用于线程间通信,也可用于父进程和子进程之间的通信,因为管道句柄可以轻松传递给所创建的子进程。在 .NET 中,可通过使用 AnonymousPipeServerStream 和 AnonymousPipeClientStream 类来实现匿名管道。

  • 命名管道。

    命名管道在管道服务器和一个或多个管道客户端之间提供进程间通信。 命名管道可以是单向的,也可以是双向的。 它们支持基于消息的通信,并允许多个客户端使用相同的管道名称同时连接到服务器进程。 命名管道还支持模拟,这样连接进程就可以在远程服务器上使用自己的权限。在 .NET 中,可通过使用 NamedPipeServerStream 和 NamedPipeClientStream 类来实现命名管道。

1、如何:使用匿名管道进行本地进程间通信

匿名管道在本地计算机上提供进程间通信。 它们提供的功能比命名管道少,但所需要的系统开销也少。 使用匿名管道,可以在本地计算机上更轻松地进行进程间通信。 不能使用匿名管道进行网络通信。

若要实现匿名管道,请使用 AnonymousPipeServerStream 和 AnonymousPipeClientStream 类。

1.1 示例 1

下面的示例展示了如何使用匿名管道将字符串从父进程发送到子进程。 本示例在父进程中创建一个 AnonymousPipeServerStream 对象,其 PipeDirection 值为 Out。然后,父进程通过使用客户端句柄创建 AnonymousPipeClientStream 对象来创建子进程。 子进程的 PipeDirection 值为 In。

接下来,父进程将用户提供的字符串发送给子进程。 字符串在子进程的控制台中显示。

下面的示例展示了服务器进程。

using System;
using System.IO;
using System.IO.Pipes;
using System.Diagnostics;class PipeServer
{static void Main(){Process pipeClient = new Process();pipeClient.StartInfo.FileName = "pipeClient.exe";using (AnonymousPipeServerStream pipeServer =new AnonymousPipeServerStream(PipeDirection.Out,HandleInheritability.Inheritable)){Console.WriteLine("[SERVER] Current TransmissionMode: {0}.",pipeServer.TransmissionMode);// Pass the client process a handle to the server.pipeClient.StartInfo.Arguments =pipeServer.GetClientHandleAsString();pipeClient.StartInfo.UseShellExecute = false;pipeClient.Start();pipeServer.DisposeLocalCopyOfClientHandle();try{// Read user input and send that to the client process.using (StreamWriter sw = new StreamWriter(pipeServer)){sw.AutoFlush = true;// Send a 'sync message' and wait for client to receive it.sw.WriteLine("SYNC");pipeServer.WaitForPipeDrain();// Send the console input to the client process.Console.Write("[SERVER] Enter text: ");sw.WriteLine(Console.ReadLine());}}// Catch the IOException that is raised if the pipe is broken// or disconnected.catch (IOException e){Console.WriteLine("[SERVER] Error: {0}", e.Message);}}pipeClient.WaitForExit();pipeClient.Close();Console.WriteLine("[SERVER] Client quit. Server terminating.");}
}

1.2 示例 2

下面的示例展示了客户端进程。 服务器进程启动客户端进程,并为此进程提供客户端句柄。 客户端代码生成的可执行文件应命名为 pipeClient.exe,并在运行服务器进程前复制到服务器可执行文件所在的相同目录中。

using System;
using System.IO;
using System.IO.Pipes;class PipeClient
{static void Main(string[] args){if (args.Length > 0){using (PipeStream pipeClient =new AnonymousPipeClientStream(PipeDirection.In, args[0])){Console.WriteLine("[CLIENT] Current TransmissionMode: {0}.",pipeClient.TransmissionMode);using (StreamReader sr = new StreamReader(pipeClient)){// Display the read text to the consolestring temp;// Wait for 'sync message' from the server.do{Console.WriteLine("[CLIENT] Wait for sync...");temp = sr.ReadLine();}while (!temp.StartsWith("SYNC"));// Read the server data and echo to the console.while ((temp = sr.ReadLine()) != null){Console.WriteLine("[CLIENT] Echo: " + temp);}}}}Console.Write("[CLIENT] Press Enter to continue...");Console.ReadLine();}
}

2、如何:使用命名管道进行网络进程间通信

命名管道在管道服务器和一个或多个管道客户端之间提供进程间通信。 它们比匿名管道(用于在本地计算机上提供进程间的通信)提供更多的功能。 命名管道支持跨网络和多个服务器实例的全双工通信、基于消息的通信以及客户端模拟,这样连接进程便可在远程服务器上使用自己的权限集。若要实现名称管道,请使用 NamedPipeServerStream 和 NamedPipeClientStream 类。

2.1 示例 1

下面的示例展示了如何使用 NamedPipeServerStream 类创建命名管道。 在此示例中,服务器进程创建四个线程。 每个线程都可以接受客户端连接。 然后,连接的客户端进程向服务器提供文件名。 如果客户端拥有足够的权限,服务器进程就会打开文件,并将它的内容发送回客户端。

using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;public class PipeServer
{private static int numThreads = 4;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){NamedPipeServerStream pipeServer =new NamedPipeServerStream("testpipe", PipeDirection.InOut, numThreads);int 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("I am the one true server!");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 = 0;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();return 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);}
}

2.2 示例 2

下面的示例展示了使用 NamedPipeClientStream 类的客户端进程。 客户端连接到服务器进程,并将文件名发送到服务器。 因为此示例使用模拟,所以运行客户端应用的标识必须有权访问文件。 然后,服务器将文件内容发送回客户端。 接下来,文件内容在控制台中显示。

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;public static void Main(string[] args){if (args.Length > 0){if (args[0] == "spawnclient"){var pipeClient =new NamedPipeClientStream(".", "testpipe",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() == "I am the one true server!"){// 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("c:\\textfile.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);}}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;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.3 可靠编程

因为此示例中的客户端进程和服务器进程可以在同一台计算机上运行,所以提供给 NamedPipeClientStream 对象的服务器名称为 "."。 如果客户端进程和服务器进程在不同的计算机上运行,"." 会被替换为运行服务器进程的计算机的网络名称。

相关文章:

【微软技术栈】C#.NET 中的管道操作

C#.NET 管道为进程间通信提供了平台。 管道分为两种类型&#xff1a; 匿名管道。 匿名管道在本地计算机上提供进程间通信。 与命名管道相比&#xff0c;虽然匿名管道需要的开销更少&#xff0c;但提供的服务有限。 匿名管道是单向的&#xff0c;不能通过网络使用。 仅支持一个服…...

Python学习笔记--进程

进程 Python 中的多线程其实并不是真正的多线程,如果想要充分地使用多核 CPU 的资源,在 Python 中大部分情况需要使用多进程。 Python 提供了非常好用的多进程包 multiprocessing,只需要定义一个函数,Python 会完成其他所有事情。 借助这个包,可以轻松完成从单进程到并…...

比亚迪刀片电池与特斯拉4680电池比较

1 电池材料 比亚迪刀片电池采用的磷酸铁锂LFP&#xff08;LiFePO4&#xff09;&#xff0c;特斯拉的4680电池采用的三元锂。 磷酸铁锂&#xff1a;循环寿命长&#xff0c;安全性能好&#xff0c;价格低廉&#xff0c;但是能量密度低&#xff0c;导电性能差&#xff0c;低温表现…...

在写windows C++代码的时候,从代码安全角度考虑,我们应该注意什么?

在写windows C代码的时候&#xff0c;从代码安全角度考虑&#xff0c;我们应该注意什么&#xff1f;分别是&#xff1a;输入验证、内存管理、错误处理、并发和线程安全、使用安全的API、避免使用不安全的函数、最小权限原则。 一、输入验证 1. 用户输入验证 #include <io…...

【草料】uni-app ts vue 小程序 如何如何通过草料生成对应的模块化二维码

一、查看uni-app项目 1、找到路径 可以看到项目从 src-race-pages-group 这个使我们目标的查询页面 下面我们将这个路径copy到草料内 2、找到进入页面入参 一般我们都会选择 onload() 函数下的入参 这里我们参数的是 id 二、草料 建议看完这里的教程文档 十分清晰&#xff01…...

CMS与FullGC

JVM中的CMS&#xff08;Concurrent Mark Sweep&#xff09;GC和Full GC&#xff08;Full Garbage Collection&#xff09;是两种不同的垃圾回收算法。 CMS GC&#xff1a;CMS GC是一种并发的垃圾回收算法&#xff0c;它在运行期间与应用程序线程并发工作&#xff0c;尽可能减少…...

一款.NET开源的小巧、智能、免费的Windows内存清理工具 - WinMemoryCleaner

前言 我们在使用Windows系统的时候经常会遇到一些程序不会释放已分配的内存&#xff0c;从而导致电脑变得缓慢。今天给大家推荐一款.NET开源的小巧、智能、免费的Windows内存清理工具&#xff1a;WinMemoryCleaner。 使用Windows内存清理工具来优化内存&#xff0c;这样不必浪…...

iptables详解:链、表、表链关系、规则的基本使用

目录 防火墙基本概念 什么是防火墙&#xff1f; Netfilter与iptables的关系 链的概念 表的概念 表链关系 规则的概念 查询规则 添加规则 删除iptables中的记录 修改规则 更详细的命令&#xff08;5链4表&#xff09; 防火墙基本概念 什么是防火墙&#xff1f; 在…...

安全管理中心(设备和技术注解)

网络安全等级保护相关标准参考《GB/T 22239-2019 网络安全等级保护基本要求》和《GB/T 28448-2019 网络安全等级保护测评要求》 密码应用安全性相关标准参考《GB/T 39786-2021 信息系统密码应用基本要求》和《GM/T 0115-2021 信息系统密码应用测评要求》 1系统管理 1.1对系统管…...

Failed to execute org.scala-tools:maven-scala-plugin:2.15.2解决

原因也不是很清楚&#xff0c;查看一个博主文章(net.alchim31.maven:scala-maven-plugin&#xff1a;maven依赖无法下载或无法编译)得到的解决方案&#xff1a; 在idea的terminal执行以下语句即可实现maven对scala代码的编译&#xff1a; mvn clean scala:compile compile pac…...

C#中委托和事件的使用总结

委托&#xff08;delegate&#xff09;特别用于实现事件和回调方法。所有的委托&#xff08;Delegate&#xff09;都派生自 System.Delegate 类。事件是一种特殊的多播委托&#xff0c;仅可以从声明事件的类或结构中对其进行调用。类或对象可以通过事件向其他类或对象通知发生的…...

基于STM32的外部中断(EXTI)在嵌入式系统中的应用

外部中断&#xff08;External Interrupt&#xff0c;EXTI&#xff09;是STM32嵌入式系统中常见且重要的功能之一。它允许外部事件&#xff08;例如按键按下、传感器触发等&#xff09;通过适当的引脚触发中断&#xff0c;从而应用于各种嵌入式系统中。在STM32微控制器中&#…...

【心得】PHP的文件上传个人笔记

目录 1 php的文件上传绕过 黑名单绕过 2 php文件上传的00截断 3 iconv字符转换异常后造成了字符截断 4 文件后缀是白名单的时候的绕过 web服务器的解析漏洞绕过 5.高级文件上传绕过 1 .htaccess nginx.htaccess 2 服务端内容检测 3 配合伪协议来绕过 4.配合日志包含绕…...

深度学习之基于Pytorch和OCR的识别文本检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介深度学习与OCRPyTorch在OCR中的应用文本检测系统的关键组成部分1. 图像预处理2. 深度学习模型3. 文本检测算法4. 后处理 二、功能三、系统四. 总结 一项目简…...

三十一、W5100S/W5500+RP2040树莓派Pico<TCP_Server多路socket>

文章目录 1 前言2 简介2. 1 使用多路socket的优点2.2 多路socket数据交互原理2.3 多路socket应用场景 3 WIZnet以太网芯片4 多路socket设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 W5100S/W5500是一…...

带你精通chrony服务器

华子目录 为什么会出现Chrony&#xff1f;Linux的两个时钟NTP介绍Chrony介绍安装与配置安装Chrony配置文件分析实验1实验2chronyc命令查看时间服务器chronyc sources输出分析其他命令 常见时区 为什么会出现Chrony&#xff1f; 由于IT系统中&#xff0c;准确的计时非常重要&am…...

vs2017 编译Qt 5.11.2 源码

SDK 10.0.22000.194 有 2种编译方式 &#xff0c;第二种 看下面 方式一: 1、问题描述&#xff1a; 使用VS编译程序时&#xff0c;运行库选择多线程&#xff08;/MT&#xff09;&#xff0c;表示采用多线程静态release的方式进行编译。 但是&#xff0c;发现编译是不能通过的…...

【SpringBoot3+Vue3】四【实战篇】-前端(vue基础)

目录 一、项目前置知识 二、使用vscode创建 三、vue介绍 四、局部使用vue 1、快速入门 1.1 需求 1.2 准备工作 1.3 操作 1.3.1 创建html 1.3.2 创建初始html代码 1.3.3 参照官网import vue 1.3.4 创建vue应用实例 1.3.5 准备div 1.3.6 准备用户数据 1.3.7 通过…...

element ui修改select选择框背景色和边框色

一、修改选择框的背景色和边框色 style部分 .custom-select /deep/ .el-input__inner {color: #fff!important;border: 1px solid #326AFF;background: #04308D !important; } html部分 <el-select class"custom-select" v-model"dhvalue" placeholde…...

软件测试人员提问常用的ChatGPT通用提示词模板

如何设计有效的软件测试用例&#xff1f; 如何运用自动化测试工具进行软件测试&#xff1f; 如何进行软件的功能测试、性能测试和安全测试&#xff1f; 如何评估软件测试的质量和覆盖范围&#xff1f; 软件测试有哪些常见的缺陷和错误&#xff0c;如何识别和解决&#xff1…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...