Windows:TCP / IP:强制关闭连接:避免内核/用户级的memleaks

时间:2011-09-10 01:58:13

标签: windows networking memory-leaks tcp

向Windows网络编程专家提问。

当我使用这样的伪代码时:

reconnect:
    s = socket(...);
    // more code...

read_reply:
    recv(...);
    // merge received data
    if(high_level_protocol_error) {
        // whoops, there was a deviation from protocol, like overflow
        // need to reset connection and discard data right now!
        closesocket(s);
        goto reconnect;
    }

内核是否取消关联并释放从NIC“物理”接收的所有数据(因为它必须真正存在于内核内存中,等待用户级别使用recv()读取它),当我closesocket()时?好吧,逻辑上应该是因为数据不再与任何内部对象相关联,对吧?

因为我真的不想浪费未知的时间进行干净关机,例如“调用recv()直到返回错误”。这没有意义:如果它永远不会返回错误,比如说,服务器会继续永久发送数据并且不会关闭连接,但这是不好的行为?

我很想知道它,因为我不希望我的应用程序在任何地方导致内存泄漏。这种强制重置连接的方式,仍然可以发送未知数据量正确吗?

//问题的可选添加:如果这个方法被认为对Windows是正确的,对于符合UNIX的操作系统,它是否可以被认为是正确的(将closesocket()更改为close())?

2 个答案:

答案 0 :(得分:1)

Windows(或任何操作系统)中的内核驱动程序(包括tcpip.sys)应该可以在所有情况下避免内存泄漏,无论您在用户模式下执行什么操作。我认为开发人员已经绘制了可能的状态,包括错误状态,以确保资源不会泄露。至于用户模式,我不完全确定,但我不认为资源在您的过程中泄露。

套接字只是Windows中的文件对象。当您关闭文件的最后一个句柄时,IO管理器会向拥有该文件的驱动程序发送IRP_MJ_CLEANUP消息,以清除与其关联的资源。与套接字关联的接收缓冲区将与文件对象一起释放。

closesocket documentation中确实说取消了挂起的操作,但是在函数返回后异步操作可能会完成。这听起来像是在使用时关闭套接字是受支持的场景,并且不会导致内存泄漏。

答案 1 :(得分:0)

没有泄漏,您没有义务在关闭前阅读EOS流。如果发送者在您关闭后仍在发送,最终将获得“连接重置”。