简体   繁体   中英

C++ Winsock Accept Memory leak/Resource Leak

I have written a small test tcp listener. Said listener listens over port 28328 and works fantastic, expect for the huge resource/memory leak that happens every single time a client connects to it.

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

While the original listener is much bigger than this and probably has a lot more problems which I haven't gotten to yet, as of right now this my biggest issue.

I assume that the issue occurs as a result of accepting of the socket and it not closing properly which then leaks to a handle leak. I base this on the fact that when I looked at task manager and other tools that monitor a process I can see the handle count increasing at the same rate as my connection happen.

Note:

1) By the looks of it the leak happens on the Non-Paged Memory.

2) This same snippet of code if compiled and used in a linux environment will not yield the same memory/resource leak.

3) I have compiled and tested this code on multiple windows machines and the same problem occurs.

4) (EDIT) I did see a couple of people with this exact problem posting on some of the MSDN forums and VS forums but all they were told to do was submit a ticket.

The non-paged-pool is a kernel resource, and relates to memory which can not be paged by the operating system, and is a scarce resource. So keeping an eye on it, is a good thing.

The fact it is in kernel, means the memory is not directly in your control. It may be that the memory relates to un-sent, un-processed packets, which case the resource is the responsibility of your program indirectly.

Check for the handle leak - where that is coming from. Application Verifier Microsoft : Application Verifier download can help identify the call stacks which are leaking memory and handles.

There's no memory leak in the application you have shown.

Due to the way TCP/IP works, resources associated with closed connections can not be freed immediately. Packets may arrive out of order or be retransmitted after the connection has been closed. So even after a call to closesocket the actual OS socket remains open for a predefined amount of time (usually 2-3 minutes, can be adjusted with TcpTimedWaitDelay).

If you run netstat -an , you'll see a bunch of connections in CLOSE_WAIT or TIME_WAIT state:

  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
  . . .

Of course (kernel) memory is needed to store these temporary states.

In addition, the TCP port number from the ephemeral range cannot be reused immediately, which means the rate at which you can open/close connections is quite limited.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM