我正在学习命名管道,并尝试使用MSDN文档中的命名管道客户端和服务器示例:
我修改了客户端,以便可以在控制台中输入消息并将其发送到服务器,服务器显示该消息并发送回复。基本上,在SetNamedPipeHandleState()调用之后,在CloseHandle()调用之前添加了一个循环(即开放和关闭发生在循环外部,因此我在循环内使用相同的管道句柄)。
我的问题是,如果我关闭客户端或通过任务管理器结束客户端,是否有任何方法让服务器端检测到断开连接?
我尝试使用GetNamedPipeHandleState(),希望它返回失败并且调用GetLastError()会返回ERROR_PIPE_NOT_CONNECTED,但事实并非如此。由于必须在CompletedReadRoutine函数中执行此操作,并创建一个“受控”失败,所以我必须按照服务器上的CompletedReadRoutine设置断点:
- 启动服务器
- 启动客户端
- 通过客户端发送消息(在此处命中服务器的断点)
- 结束客户端
- 执行到GetNamedPipeHandleState()
调用GetNamedPipeHandleState()成功返回,因此我无法执行GetLastError()调用。当它到达WriteFileEx调用时,它将失败,并且在该点调用GetLastError将返回ERROR_NO_DATA。
查看管道函数,我找不到其他可能有帮助的内容。我是否遗漏了某些东西或是客户端断开连接不可检测的情况?
我能想到的唯一另外一件事情就是通过GetNamedPipeClientProcessId收集连接客户端的pid,并开启看门狗线程来检查它们是否还存活。然而,光是想到这样做就让我的警觉感觉起来了。
在使用命名管道时,是否有一种方法可以检测到已断开连接的客户端?