本文告訴大家如何使用dot net core 和其他進程進行通信 ...
本文告訴大家如何使用dot net core 和其他進程進行通信
一般都是使用 WCF 或 remoting 做遠程通信,但是 dot net core 不支持 WCF 所以暫時我就只能使用 管道通信。
原理
管道通信使用的是 Pipe 需要啟動一對才可以
在 NamedPipeServerStream 啟動之後可以接受其他 NamedPipeClientStream 連接。
因為現在已經使用了 await 了,所以建議全部都可以寫非同步。
創建的 NamedPipeServerStream 需要告訴管道的命名,和通信方式,通信可以分為單向和雙向,大家使用枚舉去看一下就可以知道。
var pipe = new NamedPipeServerStream("lindexi", PipeDirection.InOut);
上面代碼就創建了一個管道,之後需要等待有連接才可以發送數據。
await pipe.WaitForConnectionAsync();
等待了連接之後,就可以發送數據
string str = "發送消息";
var spxnfSrxldhhv = Encoding.UTF8.GetBytes(str);
pipe.Write(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);
註意,需要指定發送數據的長度和數據,通過這個方法發送是不建議的。
如果需要使用一個比較高級的方法傳輸,請看文章最後
這時另一個程式就需要下麵代碼連接
var pipe = new NamedPipeClientStream(".", "lindexi", PipeDirection.InOut, PipeOptions.None);
pipe.Connect()
上面代碼使用的 NamedPipeClientStream 需要指定管道的命名才可以找到。
連接之後可以通過這個方式讀取數據
var spxnfSrxldhhv = new byte[65535];
var n = pipe.Read(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);
var str = Encoding.UTF8.GetString(spxnfSrxldhhv, 0, n);
對於讀寫數據很多時候就使用 pipe 的讀寫,寫入位元組,讀出位元組。
因為一次讀取可能會卡很多時間,所以建議使用非同步讀。
如果覺得每次發送都需要轉 byte 然後進行寫,代碼很多,可以使用下麵的代碼
var stream = new StreamWriter(pipe);
stream.Write("發送消息");
stream.Flush();
註意不要使用下麵的代碼
using (var stream = new StreamWriter(pipe))
{
stream.Write("發送消息");
}
原因是 using 會關閉 pipe 所以使用之後就不能在寫。
例子
首先創建兩個程式,一個是 WPF 程式 DgvlzKixtdin ,另一個是 dot net core 控制台 HclkvyDanuiag 。接著需要從 DgvlzKixtdin 發送數據,從 HclkvyDanuiag 接收數據。
在 WPF 程式添加一個 TextBlock 和 Button ,點擊 Button 就發送消息到 dot net core 程式。收到消息就在 TextBlock 顯示。
在 Button 點擊的代碼寫下麵代碼
private async void HixKkikjgp_OnClick(object sender, RoutedEventArgs e)
{
var pipe = new NamedPipeServerStream("lindexi", PipeDirection.InOut);
await pipe.WaitForConnectionAsync();
string str = "發送消息";
var spxnfSrxldhhv = Encoding.UTF8.GetBytes(str);
pipe.Write(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);
spxnfSrxldhhv = new byte[100];
var n = pipe.Read(spxnfSrxldhhv, 0, 100);
str = Encoding.UTF8.GetString(spxnfSrxldhhv, 0, n);
TjdsguhmKzj.Text = str;
}
然後在 dot net core 程式寫下麵代碼
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var pipe = new NamedPipeClientStream(".", "lindexi", PipeDirection.InOut, PipeOptions.None);
pipe.Connect();
var spxnfSrxldhhv = new byte[65535];
var n = pipe.Read(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);
var str = Encoding.UTF8.GetString(spxnfSrxldhhv, 0, n);
Console.WriteLine(str);
str = "收到";
spxnfSrxldhhv = Encoding.UTF8.GetBytes(str);
pipe.Write(spxnfSrxldhhv, 0, spxnfSrxldhhv.Length);
Console.Read();
}
先啟動 WPF 程式,然後啟動控制台
這時點擊按鈕之後就打開控制台可以看到控制台可以收到消息
然後 WPF 也收到控制台發過來的消息
序列化
雖然使用StreamWriter可以減少寫入讀取的代碼,但是實際上這樣只能用來傳字元串,需要把類傳輸還是比較難,所以我找到了 Protobuf ,使用這個庫可以簡單使用。
首先打開 Nuget 安裝 Protobuf 第一個
我這裡使用 protobuf-net
然後創建一個類用來傳輸
[ProtoContract]
public class TyfxxTlkbjn
{
public string DczSwdsun { get; set; }
}
使用下麵代碼可以進行寫入
Serializer.Serialize(pipe, 實例);
所以修改一下上面的按鈕按下
{
var pipe = new NamedPipeServerStream("lindexi", PipeDirection.InOut);
await pipe.WaitForConnectionAsync();
var tyfxxTlkbjn = new TyfxxTlkbjn()
{
DczSwdsun = "發送消息"
};
Serializer.Serialize(pipe, tyfxxTlkbjn);
pipe.Disconnect();
修改 dot net core的代碼
static void Main(string[] args)
{
var pipe = new NamedPipeClientStream(".", "lindexi", PipeDirection.InOut, PipeOptions.None);
pipe.Connect();
var tyfxxTlkbjn = Serializer.Deserialize<TyfxxTlkbjn>(pipe);
Console.WriteLine(tyfxxTlkbjn.DczSwdsun);
Console.Read();
}
如果使用 wcf 請看 .NET Core調用WCF的最佳實踐