2012-02-01 239 views
2

我有2个应用程序使用命名管道进行通信。命名管道:服务器端如何知道客户端已断开连接?

主程序调用客户端程序并创建管道服务器与之通信。客户端程序创建管道客户端。主程序可以将任何消息发送到客户端程序,并且应该以某种方式在客户端处理。当客户程序退出时,它正在向主程序发送任何消息,这意味着服务器管道应该关闭。

我没有问题实施第一部分(从服务器发送消息到客户端)使用服务器与PipeDirection.Out和客户端与PipeDirection.In。但是,当我尝试修改代码以使服务器和客户端都具有PipeDirection.InOut(为了能够将消息从客户端发送到服务器)时,代码停止工作。程序挂起时,我写作.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和客户端具有管方向==在工作):

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

我不认为你正确设置pipserver。

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

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

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

我猜他们处于僵持状态,等待其中一个人发送一些信息。

+0

在我的情况下,实际上WaitForConnection确实没问题,因为客户端会立即连接。但是你是对的,问题在于我的服务器正在从客户端读取数据,而客户端也是这样做的。所以服务器无法发送任何东西给客户端,试图写一些东西。我没有意识到我不能等待来自客户端的输入并在同一时间内向其发送消息。 – Nat 2012-02-03 09:30:36

相关问题