代码之家  ›  专栏  ›  技术社区  ›  Robert Groves

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

  •  9
  • Robert Groves  · 技术社区  · 15 年前

    我正在学习命名管道,并正在使用来自msdn文档的命名管道客户机和服务器示例:

    Named Pipe Server

    Named Pipe Client

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

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

    我试过使用getnamedpipehandleState(),希望它返回失败,调用getLastError()将返回错误“管道未连接”,但事实并非如此。由于这个服务器的设置方式,我必须在completedreadroutine函数中进行设置,并创建一个“受控”故障。我所做的是,在服务器的completedreadroutine上有一个断点:

    1. 已启动服务器
    2. 启动了客户端
    3. 通过客户端发送消息(点击服务器上的断点)
    4. 杀死了客户
    5. 进入getnamedpipehandlestate

    对getnamedpipehandleState()的调用返回成功,因此我从未进行过getLastError()调用。当它到达writefileex调用时,它将失败,此时调用getLastError将返回错误“无”数据。

    看看管道的功能,我看不出还有什么可能对这里有帮助的。我丢失了一些东西,或者是一个客户机断开连接,但无法检测到。

    我唯一能想到的另一件事是收集连接客户机的PID(通过getnamedpipeClientProcessID)并关闭看门狗线程以检查它们是否仍然存在。尽管如此,仅仅是想这么做就让我产生了强烈的感觉。

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

    2 回复  |  直到 9 年前
        1
  •  5
  •   Len Holgate    15 年前

    ReadFile() 返回和错误以及 GetLastError() 然后返回 ERROR_BROKEN_PIPE ?

        2
  •  1
  •   wombatonfire    9 年前

    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()
    

    我们正在等待一个完成包,当客户端连接时,我们切换到主循环。在主循环中,我们读取管道并通过查看 读取文件() 返回代码和 GetLastError()。 . 然后,我们再次等待一个完成包。

    客户机可以在任何阶段断开连接。完成数据包将排队,我们将 ERROR_BROKEN_PIPE .

    推荐文章