命名管道:服务器端如何知道客户端已断开连接?

时间:2012-02-01 16:55:22

标签: c# named-pipes

我有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();
    }
}

知道代码有什么问题吗?或许我想念一些基本的东西?

实际问题是我需要在服务器端知道客户端已断开连接。也许它可以通过其他方式实现?

1 个答案:

答案 0 :(得分:1)

我认为你没有正确设置pipserver。

namedPipeServerStream.WaitForConnection()将阻止当前线程,直到客户端连接。

当客户端连接到您时,然后从客户端读取一个字节,同时让客户端从服务器读取一行。

namedPipeServerStream.ReadByte();
rdr.ReadLine();

我猜他们陷入僵局,等待其中一人发送信息。