C# 命名管道示例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13806153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:51:21  来源:igfitidea点击:

Example of Named Pipes

c#ipcnamed-pipes

提问by Jordan Trainor

How do I write a simple--bare minimum needed for it to work--test application that illustrates how to use IPC/Named Pipes?

我如何编写一个简单的——它工作所需的最低限度——测试应用程序,说明如何使用 IPC/命名管道?

For example, how would one write a console application where Program 1 says "Hello World" to Program 2 and Program 2 receives message and replies "Roger That" to Program 1.

例如,如何编写一个控制台应用程序,其中程序 1 对程序 2 说“Hello World”,程序 2 接收消息并向程序 1 回复“Roger That”。

采纳答案by L.B

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();
                }
            });
        }
    }
}

回答by Martin Laukkanen

For someone who is new to IPC and Named Pipes, I found the following NuGet package to be a great help.

对于不熟悉 IPC 和命名管道的人,我发现以下 NuGet 包很有帮助。

GitHub: Named Pipe Wrapper for .NET 4.0

GitHub:用于 .NET 4.0 的命名管道包装器

To use first install the package:

要使用首先安装包:

PS> Install-Package NamedPipeWrapper

Then an example server (copied from the link):

然后是一个示例服务器(从链接复制):

var server = new NamedPipeServer<SomeClass>("MyServerPipe");
server.ClientConnected += delegate(NamedPipeConnection<SomeClass> conn)
    {
        Console.WriteLine("Client {0} is now connected!", conn.Id);
        conn.PushMessage(new SomeClass { Text: "Welcome!" });
    };

server.ClientMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
    {
        Console.WriteLine("Client {0} says: {1}", conn.Id, message.Text);
    };

server.Start();

Example client:

示例客户端:

var client = new NamedPipeClient<SomeClass>("MyServerPipe");
client.ServerMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
    {
        Console.WriteLine("Server says: {0}", message.Text);
    };

client.Start();

Best thing about it for me is that unlike the accepted answer here it supports multiple clients talking to a single server.

对我来说最好的事情是,与这里接受的答案不同,它支持多个客户端与单个服务器通信。

回答by Michael Blankenship

You can actually write to a named pipe using its name, btw.

您实际上可以使用其名称写入命名管道,顺便说一句。

Open a command shell as Administrator to get around the default "Access is denied" error:

以管理员身份打开命令外壳以绕过默认的“访问被拒绝”错误:

echo Hello > \.\pipe\PipeName

回答by patrick

FYI dotnet core on linux doesn't support namedpipes, try tcplistener instead if you're on linux

仅供参考 linux 上的 dotnet 核心不支持命名管道,如果您使用的是 linux,请尝试使用 tcplistener

This code has a client round trip a byte.

这段代码有一个客户端往返一个字节。

  • Client writes byte
  • Server reads byte
  • Server writes byte
  • Client reads byte
  • 客户端写入字节
  • 服务器读取字节
  • 服务器写入字节
  • 客户端读取字节

DotNet Core 2.0 Server ConsoleApp

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);
            }
        }
    }
}

DotNet Core 2.0 Client ConsoleApp

DotNet Core 2.0 客户端控制台应用程序

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 <-- 
            });
        }
    }
}