首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用命名管道客户机/服务器检测客户端断开连接?

如何使用命名管道客户机/服务器检测客户端断开连接?
EN

Stack Overflow用户
提问于 2010-03-03 21:58:58
回答 2查看 10K关注 0票数 10

我正在学习有关命名管道的知识,并在使用MSDN文档中的命名管道客户端和服务器示例:

命名管道服务器

命名管道客户端

我修改了客户机,这样我就可以将消息输入到控制台,并将它们发送到服务器,在服务器上显示消息并发回回复。本质上,我添加了一个循环,它在SetNamedPipeHandleState()调用之后开始,在CloseHandle()调用之前结束(即打开和关闭发生在循环之外,所以我在循环中使用相同的管道句柄)。

我的问题是,如果我杀死客户机(通过关闭它或通过任务管理器结束它),服务器端是否有检测断开连接的方法?

我尝试使用GetNamedPipeHandleState(),希望它返回失败,对GetLastError()的调用将返回ERROR_PIPE_NOT_CONNECTED,但事实并非如此。由于该服务器的设置方式,我不得不在CompletedReadRoutine函数中这样做,并创建一个“受控”故障。我所做的是,在服务器上的CompletedReadRoutine上有一个断点:

  1. 启动服务器
  2. 启动客户端
  3. 通过客户端发送消息(点击此处服务器中的断点)
  4. 杀了客户
  5. 进入GetNamedPipeHandleState

对GetNamedPipeHandleState()的调用成功返回,因此我从未执行GetLastError()调用。当它到达WriteFileEx调用时,它将失败,此时对GetLastError的调用将返回一个ERROR_NO_DATA。

看看管道函数,我在这里找不到任何可能有用的东西。我漏掉了什么东西,或者是客户断开了连接,只是无法察觉。

我唯一能想到的另一件事是收集连接客户端的pid(通过GetNamedPipeClientProcessId),然后分离出看门狗线程来检查它们是否还活着。不过,一想到要这么做就会引起我的幻觉。

在使用命名管道时,是否有检测断开连接的客户端的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-03-04 06:07:41

ReadFile()是否返回和错误,而GetLastError()则返回ERROR_BROKEN_PIPE

票数 9
EN

Stack Overflow用户

发布于 2016-06-05 20:09:16

ReadFile() + GetLastError()做得很好。下面是如何与I/O完成端口一起使用它们(我的实现是在python+ctypes中实现的,但其思想应该是明确的):

代码语言:javascript
运行
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2375320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档