我正在学习命名管道,并正在使用 MSDN 文档中的命名管道客户端和服务器示例:
我修改了客户端,这样我就可以在控制台中输入消息并将它们发送到服务器,在那里它显示消息并发回回复。本质上,我添加了一个循环,它在 SetNamedPipeHandleState() 调用之后开始并在 CloseHandle() 调用之前结束(即打开和关闭发生在循环之外,所以我在循环中使用相同的管道句柄)。
我的问题是,如果我杀死客户端(通过关闭它或通过任务管理器结束它),服务器端有什么方法可以检测到断开连接?
我尝试过使用 GetNamedPipeHandleState(),希望它返回失败,而对 GetLastError() 的调用将返回 ERROR_PIPE_NOT_CONNECTED,但事实并非如此。由于此服务器的设置方式,我必须在 CompletedReadRoutine 函数中执行此操作并创建“受控”故障。我所做的是,在服务器的 CompletedReadRoutine 上有一个断点:
- 启动服务器
- 启动客户端
- 通过客户端发送消息(在此处命中服务器中的断点)
- 杀死客户
- 单步执行 GetNamedPipeHandleState
对 GetNamedPipeHandleState() 的调用成功返回,因此我从未进行 GetLastError() 调用。当它到达 WriteFileEx 调用时,它会失败,此时对 GetLastError 的调用会返回 ERROR_NO_DATA。
查看管道功能,我看不到任何其他可能有帮助的东西。我遗漏了一些东西,或者客户端断开连接只是无法检测到。
我能想到的唯一另一件事是收集连接客户端的 pid(通过 GetNamedPipeClientProcessId)并关闭看门狗线程以检查它们是否还活着。不过,一想到这样做就会引起我的蜘蛛侠感。
使用命名管道时有没有办法检测断开连接的客户端?