C# 命名管道的示例
我如何编写一个简单的测试应用程序,演示如何使用IPC/命名管道C# 命名管道的示例,c#,ipc,named-pipes,C#,Ipc,Named Pipes,我如何编写一个简单的测试应用程序,演示如何使用IPC/命名管道 例如,如何编写一个控制台应用程序,其中程序1向程序2说“Hello World”,程序2接收消息并向程序1回复“Roger That”。对于刚接触IPC并命名为Pipes的人,我发现下面的NuGet包非常有帮助 using System; using System.IO; using System.IO.Pipes; using System.Linq; using System.Text; using System.Threadi
例如,如何编写一个控制台应用程序,其中程序1向程序2说“Hello World”,程序2接收消息并向程序1回复“Roger That”。对于刚接触IPC并命名为Pipes的人,我发现下面的NuGet包非常有帮助
using System;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
StartServer();
Task.Delay(1000).Wait();
//Client
var client = new NamedPipeClientStream("PipesOfPiece");
client.Connect();
StreamReader reader = new StreamReader(client);
StreamWriter writer = new StreamWriter(client);
while (true)
{
string input = Console.ReadLine();
if (String.IsNullOrEmpty(input)) break;
writer.WriteLine(input);
writer.Flush();
Console.WriteLine(reader.ReadLine());
}
}
static void StartServer()
{
Task.Factory.StartNew(() =>
{
var server = new NamedPipeServerStream("PipesOfPiece");
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
while (true)
{
var line = reader.ReadLine();
writer.WriteLine(String.Join("", line.Reverse()));
writer.Flush();
}
});
}
}
}
要使用“先安装”软件包,请执行以下操作:
PS> Install-Package NamedPipeWrapper
然后是一个示例服务器(从链接复制):
var server=newnamedpipeserver(“MyServerPipe”);
server.ClientConnected+=委托(NamedPipeConnection conn)
{
WriteLine(“客户端{0}现在已连接!”,conn.Id);
conn.PushMessage(新SomeClass{Text:“欢迎!”});
};
server.ClientMessage+=委托(NamedPipeConnection conn,SomeClass消息)
{
WriteLine(“客户端{0}说:{1}”,conn.Id,message.Text);
};
server.Start();
示例客户端:
var client = new NamedPipeClient<SomeClass>("MyServerPipe");
client.ServerMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
{
Console.WriteLine("Server says: {0}", message.Text);
};
client.Start();
var client=newnamedpipeclient(“MyServerPipe”);
client.ServerMessage+=委托(NamedPipeConnection conn,SomeClass消息)
{
WriteLine(“服务器说:{0}”,message.Text);
};
client.Start();
对我来说,它最好的一点是,与这里公认的答案不同,它支持多个客户机与单个服务器对话 您实际上可以使用命名管道的名称写入命名管道,顺便说一句 以管理员身份打开命令shell,以绕过默认的“访问被拒绝”错误: Linux dotnet core不支持命名管道强> 如果部署到Linux,请尝试TcpListener 此命名管道客户端/服务器代码将一个字节往返于服务器
- 客户端写入字节
- 服务器读取字节
- 服务器写入字节
- 客户端读取字节
using System;
using System.IO.Pipes;
using System.Threading.Tasks;
namespace Server
{
class Program
{
static void Main(string[] args)
{
var server = new NamedPipeServerStream("A", PipeDirection.InOut);
server.WaitForConnection();
for (int i =0; i < 10000; i++)
{
var b = new byte[1];
server.Read(b, 0, 1);
Console.WriteLine("Read Byte:" + b[0]);
server.Write(b, 0, 1);
}
}
}
}
using System;
using System.IO.Pipes;
using System.Threading.Tasks;
namespace Client
{
class Program
{
public static int threadcounter = 1;
public static NamedPipeClientStream client;
static void Main(string[] args)
{
client = new NamedPipeClientStream(".", "A", PipeDirection.InOut, PipeOptions.Asynchronous);
client.Connect();
var t1 = new System.Threading.Thread(StartSend);
var t2 = new System.Threading.Thread(StartSend);
t1.Start();
t2.Start();
}
public static void StartSend()
{
int thisThread = threadcounter;
threadcounter++;
StartReadingAsync(client);
for (int i = 0; i < 10000; i++)
{
var buf = new byte[1];
buf[0] = (byte)i;
client.WriteAsync(buf, 0, 1);
Console.WriteLine($@"Thread{thisThread} Wrote: {buf[0]}");
}
}
public static async Task StartReadingAsync(NamedPipeClientStream pipe)
{
var bufferLength = 1;
byte[] pBuffer = new byte[bufferLength];
await pipe.ReadAsync(pBuffer, 0, bufferLength).ContinueWith(async c =>
{
Console.WriteLine($@"read data {pBuffer[0]}");
await StartReadingAsync(pipe); // read the next data <--
});
}
}
}
使用系统;
使用System.IO.Pipes;
使用System.Threading.Tasks;
命名空间服务器
{
班级计划
{
静态void Main(字符串[]参数)
{
var server=newnamedpipeserverstream(“A”,PipeDirection.InOut);
WaitForConnection();
对于(int i=0;i<10000;i++)
{
var b=新字节[1];
读取(b,0,1);
Console.WriteLine(“读取字节:+b[0]);
server.Write(b,0,1);
}
}
}
}
DotNet Core 2.0客户端控制台
using System;
using System.IO.Pipes;
using System.Threading.Tasks;
namespace Server
{
class Program
{
static void Main(string[] args)
{
var server = new NamedPipeServerStream("A", PipeDirection.InOut);
server.WaitForConnection();
for (int i =0; i < 10000; i++)
{
var b = new byte[1];
server.Read(b, 0, 1);
Console.WriteLine("Read Byte:" + b[0]);
server.Write(b, 0, 1);
}
}
}
}
using System;
using System.IO.Pipes;
using System.Threading.Tasks;
namespace Client
{
class Program
{
public static int threadcounter = 1;
public static NamedPipeClientStream client;
static void Main(string[] args)
{
client = new NamedPipeClientStream(".", "A", PipeDirection.InOut, PipeOptions.Asynchronous);
client.Connect();
var t1 = new System.Threading.Thread(StartSend);
var t2 = new System.Threading.Thread(StartSend);
t1.Start();
t2.Start();
}
public static void StartSend()
{
int thisThread = threadcounter;
threadcounter++;
StartReadingAsync(client);
for (int i = 0; i < 10000; i++)
{
var buf = new byte[1];
buf[0] = (byte)i;
client.WriteAsync(buf, 0, 1);
Console.WriteLine($@"Thread{thisThread} Wrote: {buf[0]}");
}
}
public static async Task StartReadingAsync(NamedPipeClientStream pipe)
{
var bufferLength = 1;
byte[] pBuffer = new byte[bufferLength];
await pipe.ReadAsync(pBuffer, 0, bufferLength).ContinueWith(async c =>
{
Console.WriteLine($@"read data {pBuffer[0]}");
await StartReadingAsync(pipe); // read the next data <--
});
}
}
}
使用系统;
使用System.IO.Pipes;
使用System.Threading.Tasks;
命名空间客户端
{
班级计划
{
公共静态int-threadcounter=1;
公共静态NamedPipeClientStream客户端;
静态void Main(字符串[]参数)
{
client=newnamedpipeclientstream(“.”,“A”,PipeDirection.InOut,PipeOptions.Asynchronous);
client.Connect();
var t1=新系统.Threading.Thread(StartSend);
var t2=新系统.Threading.Thread(StartSend);
t1.Start();
t2.Start();
}
公共静态void StartSend()
{
int thisThread=线程计数器;
threadcounter++;
启动同步(客户端);
对于(int i=0;i<10000;i++)
{
var buf=新字节[1];
buf[0]=(字节)i;
client.WriteAsync(buf,0,1);
WriteLine($@“Thread{thisThread}编写:{buf[0]}”);
}
}
公共静态异步任务StartReadingAsync(NamedPipeClientStream管道)
{
变量缓冲长度=1;
字节[]pBuffer=新字节[bufferLength];
wait pipe.ReadAsync(pBuffer,0,bufferLength).ContinueWith(async=>
{
WriteLine($@“读取数据{pBuffer[0]}”);
等待开始同步(管道);//阅读下一个数据@JordanTrainor抱歉,它在.Net 4.5中。你可以使用线程。睡眠@Gusdor我本可以使用一些sync primiteves。但是它会更难阅读。我认为这足以让你了解如何使用namedpipes如果你在一次阅读后发现管道关闭的问题,请检查以下答案:如果你使用的是.Net4.5,你可以。你必须处理读卡器
/写卡器
?如果是的话,你只处理其中一个吗?我从来没有见过一个例子,其中两个都连接到同一个流。我不推荐这个NuGet包用于生产。我已经实现了它,它有一些bug,主要是因为无法真正知道消息何时出现ge在管道的另一端已被完全接收(导致连接中断,或连接过早结束(如果您不信任我,请检查github上的代码,“WaitForPipeDrain”在应该调用的时候不会被调用),此外,即使只有一个客户端在侦听,您也会有多个客户端,因为…问题太多)。很遗憾,因为它真的很容易使用。我不得不用更少的选项从头开始重建一个。是的,很好的一点,不幸的是,最初的维护人员已经多年没有更新项目了,幸运的是,尽管存在许多分叉,其中大多数修复了您讨论的问题。@MartinLaukkanen:您好,我计划使用NamedPipeWrapper,您知道吗哪个叉子在修复这个错误?thanks@MartinLaukkanen我们可以用fork来修复上面提到的bug吗?我不记得我具体使用了哪一个,但我建议查看fork网络图上的提交,以确定哪一个修复了您关心的问题:对2个进程使用命名管道会使我<代码>系统未经授权访问异常-路径被拒绝
不确定是否可以作为管理员运行?