基于消息传输的命名管道:
基于消息的命名管道可以传递不定长的内容,而无需传递内容长度或者结束符,上面非基于消息的传输我们都是在向管道中输入一段文本,使用WriteLine方法以回车换行作为结束符传输信息,而管道的另一端再使用ReadLine方法以读取到回车换行符作为一个消息传递结束的标志;而在使用基于消息传输时就不必这么做了
server端
class Program{
static void Main(string[] args)
{
var running = true;
while (running) // loop only for 1 client
{
PipeSecurity ps = new PipeSecurity();
//获取权限
ps.AddAccessRule(new PipeAccessRule("NETWORK SERVICE", PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule("CREATOR OWNER", PipeAccessRights.FullControl, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule("SYSTEM", PipeAccessRights.FullControl, AccessControlType.Allow));
//using (var server = new NamedPipeServerStream("PIPE_NAME", PipeDirection.InOut))
using (var server = new NamedPipeServerStream("PIPE_NAME", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.None, 2048, 2048, ps))
{
server.WaitForConnection();
Console.WriteLine("Client connected");
using (var pipe = new PipeStream(server))
{
pipe.Send("handshake");
Console.WriteLine(pipe.Receive());
server.WaitForPipeDrain();
server.Flush();
}
}
}
Console.WriteLine("server closed");
Console.Read();
}
}
public class PipeStream : IDisposable
{
private readonly Stream _stream;
private readonly Reader _reader;
private readonly Writer _writer;
public PipeStream(Stream stream)
{
_stream = stream;
_reader = new Reader(_stream);
_writer = new Writer(_stream);
}
public string Receive()
{
return _reader.ReadLine();
}
public void Send(string message)
{
_writer.WriteLine(message);
_writer.Flush();
}
public void Dispose()
{
_reader.Dispose();
_writer.Dispose();
_stream.Dispose();
}
private class Reader : StreamReader
{
public Reader(Stream stream)
: base(stream)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(false);
}
}
private class Writer : StreamWriter
{
public Writer(Stream stream)
: base(stream)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(false);
}
}
}
client端
public class NamedPipeClient
{
public NamedPipeClient() { }
public bool Start(object value)
{
try
{
using (var client = new NamedPipeClientStream(".", "PIPE_NAME", PipeDirection.InOut))
{
client.Connect(2000);
var content = JsonConvert.SerializeObject(value);
using (var pipe = new PipeStream(client))
{
pipe.Receive();
client.WaitForPipeDrain();
pipe.Send(content);
}
}
return true;
}
catch (Exception ex)
{
LogHelper.Error(typeof(NamedPipeClient), "start failed"+ex.Message+ex.StackTrace);
}
return false;
}
}
public class PipeStream : IDisposable
{
private readonly Stream _stream;
private readonly Reader _reader;
private readonly Writer _writer;
public PipeStream(Stream stream)
{
_stream = stream;
_reader = new Reader(_stream);
_writer = new Writer(_stream);
}
public string Receive()
{
return _reader.ReadLine();
}
public void Send(string message)
{
_writer.WriteLine(message);
_writer.Flush();
}
public void Dispose()
{
_reader.Dispose();
_writer.Dispose();
_stream.Dispose();
}
private class Reader : StreamReader
{
public Reader(Stream stream)
: base(stream)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(false);
}
}
private class Writer : StreamWriter
{
public Writer(Stream stream)
: base(stream)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(false);
}
}
}
IIS的配置
http://dotnetmentors.com/hosting-wcf-service-with-nettcpbinding-or-netnamedpipebinding-in-iis.aspx
网友评论