ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

System.IO之使用管道在进程间通信 (System.IO.Pipes使用)

2022-07-12 13:04:06  阅读:243  来源: 互联网

标签:string pipeStream bytes System 间通信 管道 IO 进程 new


管道的用途是在同一台机器上的进程之间通信,也可以在同一网络不同机器间通信。在.Net中可以使用匿名管道和命名管道。管道相关的类在System.IO.Pipes命名空间中。.Net中管道的本质是对windows API中管道相关函数的封装。
使用匿名管道在父子进程之间通信:
匿名管道是一种半双工通信,所谓的半双工通信是指通信的两端只有一端可写另一端可读;匿名管道只能在同一台机器上使用,不能在不同机器上跨网络使用。
匿名管道顾名思义就是没有命名的管道,它常用于父子进程之间的通信,父进程在创建子进程是要将匿名管道的句柄作为字符串传递给子进程,看下例子:
父进程创建了一个AnonymousPipeServerStream,然后启动子进程,并将创建的AnonymousPipeServerStream的句柄作为参数传递给子进程。如下代码:  
Process process = new Process();

process.StartInfo.FileName = "child.exe";

//创建匿名管道流实例,

using (AnonymousPipeServerStream pipeStream =

new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable)) {

//将句柄传递给子进程

process.StartInfo.Arguments = pipeStream.GetClientHandleAsString();

process.StartInfo.UseShellExecute = false;

process.Start();

//销毁子进程的客户端句柄?

pipeStream.DisposeLocalCopyOfClientHandle();

using (StreamWriter sw = new StreamWriter(pipeStream)) {

sw.AutoFlush = true;

//向匿名管道中写入内容

sw.WriteLine(Console.ReadLine());

}

}

process.WaitForExit();

process.Close();

 

子进程声明了一个AnonymousPipeClientStream实例,并从此实例中读取内容,如下代码:  
using (StreamReader sr = new StreamReader(

new AnonymousPipeClientStream(PipeDirection.In, args[0]))) {
string line;
while ((line = sr.ReadLine()) != null) {

Console.WriteLine("Echo: {0}", line);
}
}
这个程序要在cmd命令行中执行,否则看不到执行效果,执行的结果是在父进程中输入一行文本,子进程输出Echo:文本。
命名管道:
命名管道的功能比匿名管道更强大,可以在进程之间做双工通信(即通信的两个进程都是既可以读也可写的);命名管道也可以实现跨网络在不同机器之间进行通信。可以在多线程中创建多个NamedPipeServerStream实例,为多个client端服务。另外命名管道还支持消息传输,这样client端可以读取任意长度的消息,而无须知道消息的长度。
如下服务端进程代码:  
using (NamedPipeServerStream pipeStream = new NamedPipeServerStream("testpipe"))
{
pipeStream.WaitForConnection();
using (StreamWriter writer = new StreamWriter(pipeStream))
{
writer.AutoFlush = true;
string temp;
while ((temp = Console.ReadLine()) != "stop") {
writer.WriteLine(temp);
}
}
}
如下客户端进程代码:  
static void Main(string[] args)

{
using (NamedPipeClientStream pipeStream = new NamedPipeClientStream("testpipe"))
{

pipeStream.Connect();

//在client读取server端写的数据

using (StreamReader rdr = new StreamReader(pipeStream))

{

string temp;

while ((temp = rdr.ReadLine()) != "stop")

{

Console.WriteLine("{0}:{1}",DateTime.Now,temp);

}

}

}

Console.Read();

}
上面代码执行结果是服务端输入文本,客户端显示接受到文本的时间和文本内容。上面说了命名管道是全双工通信的,所以你也可以让客户端写内容,而服务端接受内容,代码大同小异。
基于消息传输的命名管道:
基于消息的命名管道可以传递不定长的内容,而无需传递内容长度或者结束符,上面非基于消息的传输我们都是在向管道中输入一段文本,使用WriteLine方法以回车换行作为结束符传输信息,而管道的另一端再使用ReadLine方法以读取到回车换行符作为一个消息传递结束的标志;而在使用基于消息传输时就不必这么做了。如下示例:
服务端代码:  
static void Main(string[] args)

{
UTF8Encoding encoding = new UTF8Encoding();
string message1 = "Named Pipe Message Example.";

string message2 = "Another Named Pipe Message Example.";

Byte[] bytes;

using (NamedPipeServerStream pipeStream = new

NamedPipeServerStream("messagepipe", PipeDirection.InOut, 1,

PipeTransmissionMode.Message, PipeOptions.None))

{

pipeStream.WaitForConnection();

// Let’s send two messages.

bytes = encoding.GetBytes(message1);

pipeStream.Write(bytes, 0, bytes.Length);

bytes = encoding.GetBytes(message2);

pipeStream.Write(bytes, 0, bytes.Length);

}

}
客户端代码: 
static void Main(string[] args)

{
Decoder decoder = Encoding.UTF8.GetDecoder();
Byte[] bytes = new Byte[10];

Char[] chars = new Char[10];

using (NamedPipeClientStream pipeStream =

new NamedPipeClientStream("messagepipe"))

{

pipeStream.Connect();

pipeStream.ReadMode = PipeTransmissionMode.Message;

int numBytes;

do

{

string message = "";

do

{

numBytes = pipeStream.Read(bytes, 0, bytes.Length);

int numChars = decoder.GetChars(bytes, 0, numBytes, chars, 0);

message += new String(chars, 0, numChars);

} while (!pipeStream.IsMessageComplete);

decoder.Reset();

Console.WriteLine(message);

} while (numBytes != 0);

}

}
基于消息传递信息需要在构造NamedPipeServerStream时指定PipeTransmissionMode为PipeTransmissionMode.Message;而在客户端接收时也需指定NamedPipeClientStream的ReadMode属性为PipeTransmissionMode.Message
以上只是管道使用的简单实例,真正使用时还需要考虑多线程访问控制,权限控制等。
本文内容翻译自:http://blogs.msdn.com/b/bclteam/archive/2006/12/07/introducing-pipes-justin-van-patten.aspx 根据我自己看法对原文做了一些改动。
源码下载

标签:string,pipeStream,bytes,System,间通信,管道,IO,进程,new
来源: https://www.cnblogs.com/guangzhiruijie/p/16469648.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有