IPC / 명명 된 파이프를 사용하는 방법을 보여주는 간단한 테스트 (최소한의 최소한의 작동) 테스트 응용 프로그램을 작성하려면 어떻게해야합니까?
예를 들어, 프로그램 1이 프로그램 2에 “Hello World”라고 말하고 프로그램 2가 메시지를 수신하고 “Roger That”을 프로그램 1에 응답하는 콘솔 응용 프로그램을 작성하는 방법은 무엇입니까?
답변
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();
}
});
}
}
}
답변
IPC 및 Named Pipes를 처음 사용하는 사람에게는 다음 NuGet 패키지가 큰 도움이된다는 것을 알았습니다.
GitHub : .NET 4.0 용 명명 된 파이프 래퍼
패키지를 먼저 설치하려면 :
PS> Install-Package NamedPipeWrapper
그런 다음 예제 서버 (링크에서 복사) :
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();
클라이언트 예 :
var client = new NamedPipeClient<SomeClass>("MyServerPipe");
client.ServerMessage += delegate(NamedPipeConnection<SomeClass> conn, SomeClass message)
{
Console.WriteLine("Server says: {0}", message.Text);
};
client.Start();
나에게 가장 좋은 점은 여기서 받아 들인 대답과 달리 단일 서버와 대화하는 여러 클라이언트를 지원한다는 것입니다.
답변
실제로 btw라는 이름을 사용하여 명명 된 파이프에 쓸 수 있습니다.
기본 “액세스가 거부되었습니다”오류를 해결하려면 관리자 권한으로 명령 셸을 엽니 다.
echo Hello > \\.\pipe\PipeName
답변
리눅스의 FYI 닷넷 코어는 namedpipes를 지원하지 않습니다. 리눅스에 있다면 대신 tcplistener를 사용해보십시오
이 코드에는 클라이언트 왕복 바이트가 있습니다.
- 클라이언트 쓰기 바이트
- 서버가 바이트를 읽습니다.
- 서버 쓰기 바이트
- 클라이언트가 바이트를 읽습니다.
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 클라이언트 ConsoleApp
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 <--
});
}
}
}