异步操作类:
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading;
namespace Qin.Common.NamedPipe
{
public class AsyncState
{
public byte[] Buffer { get; set; }
public PipeStream Stream { get; set; }
public MemoryStream MemoryStream { get; set; }
public ManualResetEvent EvtHandle { get; set; }
}
}
Buffer 是每次读取时获取到的字节码。
PipeStream 是客户端与服务端的父类,方便后面客户端与服务端都用到,所以就定义了他们的父类。
MemoryStream 是获取到的所有的字节码,用完后就清空。
EVTHandle 是用来阻塞进程的,就是没读取完就不执行下一行代码。
服务端:
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading;
namespace Qin.Common.NamedPipe
{
public class MyServer
{
private NamedPipeServerStream Server { get; set; }
private byte[] Buffer;
private int BufferSize = 10;
private StringBuilder InputStr { get; set; }
public MyServer(string name)
{
this.Server = new NamedPipeServerStream(name,
PipeDirection.InOut,
1,
PipeTransmissionMode.Message,
PipeOptions.None);
this.InputStr = new StringBuilder();
Buffer = new byte[BufferSize];
}
public void Start()
{
while (true)
{
this.Server.WaitForConnection();
AsyncState asyncState = new AsyncState()
{
Buffer = new byte[BufferSize],
EvtHandle = new ManualResetEvent(false),
Stream = this.Server
};
//异步读取,并阻塞线程,读取结束取消阻塞
this.Server.BeginRead(this.Buffer, 0, this.Buffer.Length, new AsyncCallback(ReadCallback), asyncState);
asyncState.EvtHandle.WaitOne();
//获取输出字符串
string outStr = "";
if (Readed != null) outStr = this.Readed.Invoke(this.InputStr.ToString().Replace("\0", " ").Trim()).Trim();
this.InputStr.Clear();
for (int i = 0; i < this.BufferSize; i++)
outStr = " " + outStr;
//输出到内存流,然后内存流转写字节码到服务流中
using (MemoryStream memoryStream = new MemoryStream())
using (StreamWriter write = new StreamWriter(memoryStream))
{
write.Write(outStr);
write.Flush();
memoryStream.Flush();
int length = 0;
memoryStream.Position = 0;
byte[] tmp = new byte[BufferSize];
while (((length = memoryStream.Read(tmp, 0, this.Buffer.Length)) != 0))
{
Server.Write(tmp, 0, length);
}
}
Server.WaitForPipeDrain();
Server.Flush();
Server.Disconnect();
}
}
private void ReadCallback(IAsyncResult arg)
{
AsyncState state = arg.AsyncState as AsyncState;
int length = state.Stream.EndRead(arg);
if (length > 0)
{
byte[] buffer;
if (length == BufferSize) buffer = state.Buffer;
else
{
buffer = new byte[length];
Array.Copy(state.Buffer, 0, buffer, 0, length);
}
if (state.MemoryStream == null) state.MemoryStream = new MemoryStream();
state.MemoryStream.Write(buffer, 0, buffer.Length);
state.MemoryStream.Flush();
}
if (length < BufferSize)
{
state.MemoryStream.Position = 0;
using (StreamReader reader = new StreamReader(state.MemoryStream))
{
this.InputStr.Append(reader.ReadToEnd());
}
state.MemoryStream.Close();
state.MemoryStream.Dispose();
state.MemoryStream = null;
state.EvtHandle.Set();
}
else
{
Array.Clear(state.Buffer, 0, BufferSize);
//再次执行异步读取操作
state.Stream.BeginRead(state.Buffer, 0, BufferSize, new AsyncCallback(ReadCallback), state);
}
}
public event Func<string, string> Readed;
}
}
客户端:
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading;
namespace Qin.Common.NamedPipe
{
public class MyClient
{
private NamedPipeClientStream Client { get; set; }
private byte[] Buffer { get; set; }
private bool IsReadEnd { get; set; }
private bool IsWriteEnd { get; set; }
private int BufferSize = 10;
private StringBuilder InputStr { get; set; }
private string OutputStr { get; set; }
public MyClient(string serverName, string serverHost)
{
Client = new NamedPipeClientStream(serverHost, serverName);
this.Buffer = new byte[BufferSize];
this.InputStr = new StringBuilder();
}
public string Request(string outPutStr)
{
this.OutputStr = outPutStr.Trim();
this.Client.Connect();
for (int i = 0; i < this.BufferSize; i++)
this.OutputStr = " "+this.OutputStr;
using (MemoryStream memoryStream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(memoryStream))
{
writer.Write(OutputStr);
writer.Flush();
memoryStream.Flush();
int length = 0;
memoryStream.Position = 0;
while ((length = memoryStream.Read(Buffer, 0, Buffer.Length)) != 0)
{
this.Client.Write(Buffer, 0, length);
}
this.Client.WaitForPipeDrain();
this.Client.Flush();
}
AsyncState asyncState = new AsyncState()
{
Buffer = new byte[BufferSize],
EvtHandle = new ManualResetEvent(false),
Stream = this.Client
};
IAsyncResult readAsyncResult = this.Client.BeginRead(this.Buffer, 0, this.Buffer.Length, new AsyncCallback(ReadCallback), asyncState);
asyncState.EvtHandle.WaitOne();
this.Client.Close();
this.Client.Dispose();
return this.InputStr.ToString().Replace("\0", " ").Trim();
}
private void ReadCallback(IAsyncResult arg)
{
AsyncState state = arg.AsyncState as AsyncState;
int length = state.Stream.EndRead(arg);
if (length > 0)
{
byte[] buffer;
if (length == BufferSize) buffer = state.Buffer;
else
{
buffer = new byte[length];
Array.Copy(state.Buffer, 0, buffer, 0, length);
}
if (state.MemoryStream == null) state.MemoryStream = new MemoryStream();
state.MemoryStream.Write(buffer, 0, buffer.Length);
state.MemoryStream.Flush();
}
if (length < BufferSize)
{
state.MemoryStream.Position = 0;
using (StreamReader reader = new StreamReader(state.MemoryStream))
{
this.InputStr.Append(reader.ReadToEnd());
}
state.MemoryStream.Close();
state.MemoryStream.Dispose();
state.MemoryStream = null;
state.EvtHandle.Set();
}
else
{
Array.Clear(state.Buffer, 0, BufferSize);
//再次执行异步读取操作
state.Stream.BeginRead(state.Buffer, 0, BufferSize, new AsyncCallback(ReadCallback), state);
}
}
}
}
服务端调用:
class Program
{
static void Main(string[] args)
{
Server2();
Console.ReadLine();
}
public static void Server2()
{
MyServer server = new MyServer("test_pipe");
server.Readed += server_Readed;
server.Start();
}
static string server_Readed(string arg)
{
Console.WriteLine("客户端输入:\r\n{0}\r\n", arg);
return string.Format(" 字符串长度:{0} ", arg.Length);
}
}
客户端调用:
class Program
{
static void Main(string[] args)
{
while (true)
{
Client2();
}
}
public static void Client2()
{
MyClient client = new MyClient("test_pipe", ".");
Console.Write("请输入发送字符串:");
Console.WriteLine("服务端输出:\r\n" + client.Request(Console.ReadLine()));
}