Windows:TCP/IP:强制关闭连接:避免内核/用户级别的内存泄漏

发布于 2024-12-03 14:50:30 字数 866 浏览 1 评论 0原文

请教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 是正确的,那么它是否可以被认为是正确的(将 closesocket() 更改为 close() ) UNIX 兼容操作系统?

A question to windows network programming experts.

When I use pseudo-code like this:

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;
    }

Does kernel un-associate and frees all data "physically" received from NIC(since it must really already be there, in kernel memory, waiting for user-level to read it with recv()), when I closesocket()? Well, it logically should since data is not associated with any internal object anymore, right?

Because I don't really want to waste unknown amount of time for clean shutdown like "call recv() until returns error". That does not make sense: what if it will never return error, say, server continues to send data forever and not closes connection, but that is bad behaviour?

I'm wondering about it since I don't want my application to cause memory leaks anywhere. Is this way of forced resetting connection, that still expected to send in unknown amount of data correct?

// optional addition to question: if this method considered correct for windows, can it be considered correct (with change of closesocket() to close() ) for UNIX-compliant OS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海里的那抹蓝 2024-12-10 14:50:30

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

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

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

Kernel drivers in Windows (or any OS really), including tcpip.sys, are supposed to avoid memory leaks in all circumstances, regardless of what you do in user mode. I would think that the developers have charted the possible states, including error states, to make sure that resources aren't leaked. As for user mode, I'm not exactly sure but I wouldn't think that resources are leaked in your process either.

Sockets are just file objects in Windows. When you close the last handle to a file, the IO manager sends a IRP_MJ_CLEANUP message to the driver that owns the file to clean up resources associated with it. The receive buffers associated with the socket would be freed along with the file object.

It does say in the closesocket documentation that pending operations are canceled but that async operations may complete after the function returns. It sounds like closing the socket while in use is a supported scenario and wouldn't lead to a memory leak.

心是晴朗的。 2024-12-10 14:50:30

不会有泄漏,并且您没有义务在关闭之前读取 EOS 的流。如果发送者在您关闭后仍在发送,它最终会得到“连接重置”。

There will be no leak and you are under no obligation to read the stream to EOS before closing. If the sender is still sending after you close it will eventually get a 'connection reset'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文