【发布时间】:2012-02-01 16:55:22
【问题描述】:
我有 2 个应用程序使用命名管道进行通信。
主程序调用客户端程序并创建管道服务器与之通信。客户端程序创建管道客户端。主程序可以向客户端程序发送任何消息,它们应该以某种方式在客户端进行处理。当客户端程序退出时,它正在向主程序发送任何消息,这意味着应该关闭服务器管道。
使用带有 PipeDirection.Out 的服务器和带有 PipeDirection.In 的客户端来实现第一部分(从服务器向客户端发送消息)没有问题。但是当我尝试修改代码以使服务器和客户端都具有 PipeDirection.InOut (以便能够从客户端向服务器发送消息)时,代码停止工作。当我执行 writer.Flush(在服务器端)或 writer.WriteByte(在客户端)时,程序挂起。它现在挂起的地方被标记为 [HANGS HERE]。
服务器是这样创建的:
public static void CreatePipeServerStream()
{
var namedPipeServerStream = new NamedPipeServerStream("somename", PipeDirection.InOut);
namedPipeServerStream.WaitForConnection();
// This thread is wating for message from client
ThreadStart starter = () => WaitForSignalFromClient(namedPipeServerStream);
new Thread(starter).Start();
}
private static void WaitForSignalFromClient(NamedPipeServerStream namedPipeServerStream)
{
if (namedPipeServerStream.IsConnected)
{
namedPipeServerStream.ReadByte();
// we'll get here after something is read
// and if we got here, we should close the server pipe
// now I can get here only if I shut down the client program using Task manager
namedPipeServerStream.Close();
}
}
向客户端发送消息的过程正在执行此操作(用于在服务器具有管道方向 == Out 并且客户端具有管道方向 == In 时工作):
public static void SendMessageUsingPipe(NamedPipeServerStream namedPipeServerStream)
{
if (namedPipeServerStream.IsConnected)
{
var sw = new StreamWriter(namedPipeServerStream);
sw.WriteLine("smth");
// [HANGS HERE]
sw.Flush();
}
}
在客户端,这段代码在单独的线程中运行:
private void WaitServerCommands()
{
_pipe = new NamedPipeClientStream(".", "somename", PipeDirection.InOut);
using (var rdr = new StreamReader(_pipe))
{
while (true)
{
if (!_pipe.IsConnected)
{
_pipe.Connect();
}
rdr.ReadLine();
// I don't care what was sent by server, I just need to know that something was sent
Invoke(_handleCommand);
}
}
}
应该向服务器发送消息的代码:
private void ClosePipes()
{
if (_pipe != null && _pipe.IsConnected)
{
// [HANGS HERE]
_pipe.WriteByte(113);
_pipe.WaitForPipeDrain();
_pipe.Close();
}
}
知道代码有什么问题吗?或者,也许我错过了一些基本的东西?
实际问题是我需要在服务器端知道客户端已断开连接。也许可以通过其他方式实现?
【问题讨论】:
标签: c# named-pipes