Skip to content

Instantly share code, notes, and snippets.

@ichiroku11
Last active January 25, 2022 05:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ichiroku11/80faa8675c5354245001759733df1348 to your computer and use it in GitHub Desktop.
Save ichiroku11/80faa8675c5354245001759733df1348 to your computer and use it in GitHub Desktop.
.NETで名前付きパイプを試す
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NamedPipe.ConsoleApp {
// BinaryReaderの拡張メソッドを定義
public static class BinaryReaderExtensions {
// オブジェクトの読み込み
public static TObject ReadObject<TObject>(this BinaryReader reader) {
// 長さを読み込んでから、バイト配列を読み込む
var length = reader.ReadInt32();
var bytes = reader.ReadBytes(length);
var converter = new ObjectConverter<TObject>();
return converter.FromByteArray(bytes);
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NamedPipe.ConsoleApp {
// BinaryWriterの拡張メソッドを定義
public static class BinaryWriterExtensions {
// オブジェクトの書き込み
public static void WriteObject<TObject>(this BinaryWriter writer, TObject obj) {
var converter = new ObjectConverter<TObject>();
var bytes = converter.ToByteArray(obj);
// 長さを書き込んでからバイト配列を書き込む
writer.Write(bytes.Length);
writer.Write(bytes);
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NamedPipe.ConsoleApp {
// メッセージ
[Serializable]
public class Message {
public int Id { get; set; }
public string Content { get; set; }
public override string ToString() {
return $@"{{ {nameof(Id)} = {Id}, {nameof(Content)} = ""{Content}"" }}";
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace NamedPipe.ConsoleApp {
// オブジェクトとバイト配列の変換
public class ObjectConverter<TObject> {
private readonly IFormatter _formatter;
public ObjectConverter(IFormatter formatter = null) {
_formatter = formatter ?? new BinaryFormatter();
}
// オブジェクト=>バイト配列
public byte[] ToByteArray(TObject obj) {
using (var stream = new MemoryStream()) {
_formatter.Serialize(stream, obj);
return stream.ToArray();
}
}
// バイト配列=>オブジェクト
public TObject FromByteArray(byte[] bytes) {
using (var stream = new MemoryStream(bytes)) {
return (TObject)_formatter.Deserialize(stream);
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NamedPipe.ConsoleApp {
class Program {
// クライアント
private static async Task<Message> Client(int clientId, Message request) {
using (var stream = new NamedPipeClientStream("testpipe")) {
// サーバに接続
Console.WriteLine($"Client#{clientId} connecting");
await stream.ConnectAsync();
Console.WriteLine($"Client#{clientId} connected");
// サーバにリクエストを送信する
Console.WriteLine($"Client#{clientId} {nameof(request)}: {request}");
using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) {
writer.WriteObject(request);
}
// サーバからレスポンスを受信する
var response = default(Message);
using (var reader = new BinaryReader(stream, Encoding.UTF8, true)) {
response = reader.ReadObject<Message>();
}
Console.WriteLine($"Client#{clientId} {nameof(response)}: {response}");
return response;
}
}
// サーバ
private static async Task Server(int serverId, Func<Message, Message> process) {
while (true) {
//using (var stream = new NamedPipeServerStream("testpipe")) {
// サーバインスタンスを2に
using (var stream = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 2)) {
// クライアントからの接続を待つ
Console.WriteLine($"Server#{serverId} waiting");
await stream.WaitForConnectionAsync();
Console.WriteLine($"Server#{serverId} connected");
// クライアントからリクエストを受信する
var request = default(Message);
using (var reader = new BinaryReader(stream, Encoding.UTF8, true)) {
request = reader.ReadObject<Message>();
}
Console.WriteLine($"Server#{serverId} {nameof(request)}: {request}");
// リクエストを処理してレスポンスを作る
var response = process(request);
// クライアントにレスポンスを送信する
Console.WriteLine($"Server#{serverId} {nameof(response)}: {response}");
using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) {
writer.WriteObject(response);
}
}
}
}
// サーバでの処理
// Contentの文字列を逆順にする処理
private static Message ServerProcess(Message message) {
return new Message {
Id = message.Id,
Content = new string(message.Content.Reverse().ToArray()),
};
}
static void Main(string[] args) {
Task.WaitAll(new[] {
// クライアント
Client(1, new Message { Id = 10, Content = "あいうえお", }),
Client(2, new Message { Id = 20, Content = "かきくけこ", }),
// サーバ
//Server(1, ServerProcess),
Server(1, ServerProcess),
Server(2, ServerProcess),
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment