我正在尝试创建一个防御性命名管道服务器,其他应用程序可以读取一个简单的状态值。我对只有一个命名管道实例感兴趣,客户端将在其中连接、读取状态和断开连接。
我遇到的问题是试图保护我的管道免受不当使用;特别是防止单个进程控制并且永远不会放开我的命名管道。我试图在超时后强制断开/关闭管道以终止连接;该尝试允许我的服务器继续,但是,当我结束连接时不会调用异步回调。
我的代码的最小化版本如下(.NET 3.5)...
服务器端]
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
NamedPipeServerStream pipe = new NamedPipeServerStream("TestSimplePipe", PipeDirection.Out);
Console.WriteLine("Waiting for client...");
pipe.WaitForConnection();
Console.WriteLine("About to BeginWrite...");
pipe.BeginWrite(new byte[1] { 0x00 }, 0, 1, new AsyncCallback(ProcessWrite), pipe);
Console.WriteLine("Waiting...");
bool hasSignal = autoEvent.WaitOne(5000);
if (hasSignal == false)
{
Console.WriteLine("Client took to long.");
}
Console.WriteLine("Closing pipe.");
pipe.Close();
Console.ReadLine();
}
static void ProcessWrite(IAsyncResult result)
{
try
{
Console.WriteLine("Ending write...");
NamedPipeServerStream pipe = result.AsyncState as NamedPipeServerStream;
pipe.EndWrite(result);
Console.WriteLine("Wrote successfully!");
}
catch (Exception)
{
Console.WriteLine("Write not completed.");
}
autoEvent.Set();
}
客户端]
static void Main(string[] args)
{
using (NamedPipeClientStream npcs = new NamedPipeClientStream(".", "TestSimplePipe", PipeDirection.In))
{
Console.WriteLine("Connecting to server...");
npcs.Connect();
Console.WriteLine("Connected!");
//Thread.Sleep(15000);
Console.WriteLine("Reading byte...");
npcs.ReadByte();
Console.WriteLine("Byte read!");
}
Console.WriteLine("Done!");
Console.ReadLine();
}
如果一切都按计划设计,我会得到以下输出:
服务器端]
Waiting for client...
About to BeginWrite...
Waiting...
Ending write...
Wrote successfully!
Closing pipe.
客户端]
Connecting to server...
Connected!
Reading byte...
Byte read!
Done!
但是,如果我在客户端代码中启用睡眠,服务器将不会从回调中输出任何内容:
Waiting for client...
About to BeginWrite...
Waiting...
Client took to long.
Closing pipe.
我假设在关闭时,将调用回调并抛出“ObjectDisposedException”。相反,当我关闭服务器管道时不会调用回调。
还让我害怕的是,如果我等待客户端睡眠的整个持续时间而不结束我的服务器管道应用程序,则将在服务器上调用回调,并且我将收到服务器的以下输出:
Waiting for client...
About to BeginWrite...
Waiting...
Client took to long.
Closing pipe.
Ending write...
Write not completed.
我不担心清理异步调用,但担心由于第三方应用程序它会以某种方式保持活动状态。当我终止回调附加到的管道时,如何正确清理异步回调?