命名管道:服务器端如何知道客户端已断开连接?
Posted
技术标签:
【中文标题】命名管道:服务器端如何知道客户端已断开连接?【英文标题】:Named pipes: how server side can know that client has disconnected? 【发布时间】: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();
知道代码有什么问题吗?或者,也许我错过了一些基本的东西?
实际问题是我需要在服务器端知道客户端已断开连接。也许可以通过其他方式实现?
【问题讨论】:
【参考方案1】:我认为您的 pipserver 设置不正确。
namedPipeServerStream.WaitForConnection() 将阻塞当前线程,直到客户端连接。
当客户端确实连接时,您从客户端读取一个字节,同时您让客户端从服务器读取一行。
namedPipeServerStream.ReadByte();
rdr.ReadLine();
我猜他们正处于僵持状态,等待其中一个发送一些信息。
【讨论】:
在我的情况下 WaitForConnection 实际上没问题,因为客户端几乎会立即连接。但你是对的,问题是我的服务器正在从客户端读取 smth,而客户端也在做同样的事情。所以服务器无法向客户端发送任何东西,一直在尝试写东西。我没有意识到我不能等待来自客户端的输入并同时向它发送消息。以上是关于命名管道:服务器端如何知道客户端已断开连接?的主要内容,如果未能解决你的问题,请参考以下文章