gpt4 book ai didi

C++ Winsock 接受内存泄漏/资源泄漏

转载 作者:太空宇宙 更新时间:2023-11-04 12:56:17 24 4
gpt4 key购买 nike

我写了一个小测试 tcp 监听器。所述监听器通过端口 28328 监听并且工作得很好,每次客户端连接到它时都会发生巨大的资源/内存泄漏。

#include <stdio.h>

#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

SOCKET Socket = INVALID_SOCKET;

bool TestServer()
{
WSADATA wsaData = { 0 };
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
return false;

sockaddr_in addr = { 0 };

Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

int Enable = 1;
setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&Enable, sizeof(int));

addr.sin_family = AF_INET;
addr.sin_port = htons(28328);
addr.sin_addr.s_addr = INADDR_ANY;

if (bind(Socket, (sockaddr*)&addr, sizeof(sockaddr)))
return false;

if (listen(Socket, 50))
return false;

return true;
}


void Dolisten()
{
if (TestServer())
{
sockaddr_in addr = { 0 };

SOCKET Client_Socket = 0;

int Lenght = sizeof(addr);

for (;;)
{
Client_Socket = INVALID_SOCKET;

Client_Socket = accept(Socket, (struct sockaddr *)&addr, &Lenght);

if (Client_Socket == INVALID_SOCKET)
continue;

printf("Client Connected %X\n", Client_Socket);

shutdown(Client_Socket, 2);
closesocket(Client_Socket);
}
}
}


int main(int argc, char* argv[])
{
Dolisten();

WSACleanup();

return 0;
}

虽然原始听众比这大得多,而且可能还有很多我还没有解决的问题,但到目前为止,这是我最大的问题。

我假设问题的发生是由于接受了套接字并且它没有正确关闭然后泄漏到句柄泄漏。我基于这样一个事实,即当我查看任务管理器和其他监控进程的工具时,我可以看到句柄数以与我的连接发生相同的速率增加。

注意:

1) 从外观上看,泄漏发生在非分页内存上。

2) 如果在 linux 环境中编译和使用相同的代码片段,将不会产生相同的内存/资源泄漏。

3)我在多台windows机器上编译和测试了这段代码,都出现了同样的问题。

4)(编辑)我确实看到一些人在某些 MSDN 论坛和 VS 论坛上发帖时遇到了这个确切的问题,但他们被告知要做的只是提交一张票。

最佳答案

您显示的应用程序中没有内存泄漏。

由于 TCP/IP 的工作方式,无法立即释放与已关闭连接关联的资源。数据包可能会乱序到达或在连接关闭后重新传输。因此,即使在调用 closesocket 之后,实际的操作系统套接字仍会在预定义的时间内保持打开状态(通常为 2-3 分钟,可以使用 TcpTimedWaitDelay 进行调整)。

如果您运行 netstat -an,您将看到一堆处于 CLOSE_WAIT 或 TIME_WAIT 状态的连接:

  TCP    127.0.0.1:28328        127.0.0.1:56508        TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56510 TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56512 TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56514 TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56516 TIME_WAIT
. . .

当然需要(内核)内存来存储这些临时状态。

此外,临时范围内的 TCP 端口号不能立即重复使用,这意味着您可以打开/关闭连接的速率非常有限。

关于C++ Winsock 接受内存泄漏/资源泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46514514/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com