【问题标题】:Handle leak when socket is forcibly closed by remote host? (.net)远程主机强制关闭套接字时处理泄漏? (。网)
【发布时间】:2010-02-18 09:49:28
【问题描述】:

我创建了一个简单的基于 tcp 的“回显协议”,并注意到当客户端强行关闭连接(发送重置)时,服务器上的句柄泄漏。

我捕获 ConnectionReset 并以与关闭套接字时相同的方式处理套接字(socket.Shutdown 和 socket.close)。有人遇到过这样的问题吗? ConnectionReset 异常在我做 socket.Read 时抛出,如果重要的话。

谢谢。

编辑:Microsoft 的 DebugDiag 工具建议这些是 MSCORLIB 创建的事件处理程序。不用说我不会直接创建它们(但它们是由 .net 库在某处创建的)

【问题讨论】:

    标签: .net sockets memory-leaks


    【解决方案1】:

    不幸的是,Socket.Recieve 和 Socket.Write 是唯一可以检测到另一端何时强制而不是正确关闭其套接字的地方。

    Socket.Close() 应该(根据我的智能感知)释放套接字句柄。

    所以首先确保Socket.Close() 确实被调用了。然后检查其他地方是否有句柄泄漏,您是否使用了任何需要处理但未被处理的对象?比如打开FileStreams?

    【讨论】:

    • 确实被调用了。没有文件流,但无论如何,我确实将重置套接字视为很好地关闭的套接字。 (我在执行读取时确实遇到了异常)
    【解决方案2】:

    我认为你做得对:

    Socket.Close 应该释放与套接字关联的所有托管和非托管资源。

    但是你是否也尝试过设置

    socket = null;
    

    也许(在那之后)使用

    GC.Collect();
    

    手动触发垃圾收集器,之后泄漏是否仍然存在?

    另一个想法: 如何监控手柄泄漏?操作系统可能会在内存中保持关闭的 TCP 连接很长时间(几分钟),这是正常行为。

    【讨论】:

    • 是的,我正在做所有这些,但泄漏仍然存在。我在任务管理器中看到句柄泄漏,但运行 net stat 显示没有等待关闭的连接。 Microsoft 的 DebugDiag 工具表明这些句柄是事件句柄,这是我得到的唯一线索。
    • 好的,在销毁接受的 TcpListener 对象后是否也存在泄漏?
    • 不,不是(我一开始以为是,但我错了)。这告诉我们什么?毕竟,我时不时地阻止不了听众
    • 我猜它只是告诉我们句柄仍然关联而不是“丢失”。也许您必须提供更多代码。所涉及的线程或对象是否仍然可以引用套接字?
    猜你喜欢
    • 2011-11-04
    • 2011-10-20
    • 2014-07-30
    • 2017-10-10
    • 2019-01-14
    • 1970-01-01
    • 2023-03-31
    • 2011-01-06
    • 2013-08-08
    相关资源
    最近更新 更多