我正在学习有关命名管道的知识,并在使用MSDN文档中的命名管道客户端和服务器示例:
我修改了客户机,这样我就可以将消息输入到控制台,并将它们发送到服务器,在服务器上显示消息并发回回复。本质上,我添加了一个循环,它在SetNamedPipeHandleState()调用之后开始,在CloseHandle()调用之前结束(即打开和关闭发生在循环之外,所以我在循环中使用相同的管道句柄)。
我的问题是,如果我杀死客户机(通过关闭它或通过任务管理器结束它),服务器端是否有检测断开连接的方法?
我尝试使用GetNamedPipeHandleState(),希望它返回失败,对GetLastError()的调用将返回ERROR_PIPE_NOT_CONNECTED,但事实并非如此。由于该服务器的设置方式,我不得不在CompletedReadRoutine函数中这样做,并创建一个“受控”故障。我所做的是,在服务器上的CompletedReadRoutine上有一个断点:
对GetNamedPipeHandleState()的调用成功返回,因此我从未执行GetLastError()调用。当它到达WriteFileEx调用时,它将失败,此时对GetLastError的调用将返回一个ERROR_NO_DATA。
看看管道函数,我在这里找不到任何可能有用的东西。我漏掉了什么东西,或者是客户断开了连接,只是无法察觉。
我唯一能想到的另一件事是收集连接客户端的pid(通过GetNamedPipeClientProcessId),然后分离出看门狗线程来检查它们是否还活着。不过,一想到要这么做就会引起我的幻觉。
在使用命名管道时,是否有检测断开连接的客户端的方法?
发布于 2010-03-04 06:07:41
ReadFile()
是否返回和错误,而GetLastError()
则返回ERROR_BROKEN_PIPE
发布于 2016-06-05 20:09:16
ReadFile()
+ GetLastError()
做得很好。下面是如何与I/O完成端口一起使用它们(我的实现是在python+ctypes中实现的,但其思想应该是明确的):
def connect():
GetQueuedCompletionStatus()
receive()
def receive():
while True:
ret_code = ReadFile()
if ret_code == 0 and GetLastError() == ERROR_BROKEN_PIPE:
# client disconnected
GetQueuedCompletionStatus()
我们在等待一个完成包,当客户端连接时,我们切换到主循环。在主循环中,我们读取管道并通过查看ReadFile()
、返回代码和GetLastError()
来检查客户端是否断开了连接。再一次,我们将等待一个完成包。
客户可以在任何阶段断开连接。完成包将排队,我们将得到ERROR_BROKEN_PIPE
。
https://stackoverflow.com/questions/2375320
复制相似问题