我有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();
}
}
知道代码有什么问题吗?或许我想念一些基本的东西?
实际问题是我需要在服务器端知道客户端已断开连接。也许它可以通过其他方式实现?
答案 0 :(得分:1)
我认为你没有正确设置pipserver。
namedPipeServerStream.WaitForConnection()将阻止当前线程,直到客户端连接。
当客户端连接到您时,然后从客户端读取一个字节,同时让客户端从服务器读取一行。
namedPipeServerStream.ReadByte();
rdr.ReadLine();
我猜他们陷入僵局,等待其中一人发送信息。