user1348950
user1348950

Reputation: 63

Looping a socket connection attempt eventually disconnects the internet connection

char IP[30] = "127.0.0.1";
char PORT[10] = "1000";

void Connection(HWND hwnd)
{
    WORD wVersionRequested;
    WSADATA wsaData;
    char * ip = "";
    PHOSTENT hostinfo;
    wVersionRequested = MAKEWORD( 2, 0 );
    int ConRes, ConRes2;
    char Buffer [20] = "";

    if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
    {
        if((hostinfo = gethostbyname(IP)) != NULL)
        {
            ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
        }   
    }

    InitWSA();

    begin:

    Sleep(1000);
    RemAdr.sin_family = AF_INET;
    RemAdr.sin_addr.s_addr=inet_addr(127.0.0.2);
    RemAdr.sin_port = htons (atoi(PORT));
    client = socket (AF_INET,SOCK_STREAM,0);

    switch(connect (client, (struct sockaddr *)&RemAdr,sizeof(RemAdr)))
    {
    case 0:
        WSAAsyncSelect(client,hwnd,RATMSG_SOCKET,FD_READ|FD_CLOSE|FD_CONNECT);
        return;
        break;

    default:
        Sleep(1000);    
        RemAdr.sin_family = AF_INET;
        RemAdr.sin_addr.s_addr=inet_addr(ip);
        RemAdr.sin_port = htons (atoi(PORT));
        client = socket (AF_INET,SOCK_STREAM,0);
        ConRes2=connect (client, (struct sockaddr *)&RemAdr,sizeof(RemAdr));
        break;
    }

    switch(ConRes2)
    {
    case 0:
        WSAAsyncSelect(client,hwnd,RATMSG_SOCKET,FD_READ|FD_CLOSE|FD_CONNECT);
        return;
        break;

    default:
        goto begin;
        break;
    }

    return;
}

After a few hours of attempting to connect and failing the connection, the user's internet will eventually disconnect until you close the application. What seems to be the problem? I think my code is a little sloppy though, so any helpful tips would be great, would love to learn.

In this I was actually trying to make a way for it to have a "backup" IP address to connect to should the first one fail. So if it can't connect to 127.0.0.1, try 127.0.0.2 next, then back to 127.0.0.1 for exmaple. How can I manage that?

P.S. anything you see in my code that seems like a "bad habit" please point it out so I can learn/fix it in the future. Thanks.

Upvotes: 1

Views: 716

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 598039

You have a handle leak. If the first connect() fails, you are calling socket() to allocate a new SOCKET handle and assigning it to the same client variable, losing the SOCKET you had previously allocated. If the second call to connect() fails, your loop calls socket() again and assigns it to the same client variable again, and again and again, over and over, until connect() finally success, if ever. That is going to waste resources over time. You need to get rid of the extra socket() calls. Call socket() only once before entering the loop, and then have the loop call connect() for each IP using the existing SOCKET you already have.

Edit try something more like this:

std::string IP = "127.0.0.1";                 
std::string IP2 = "127.0.0.2";                 
std::string PORT = "1000";                 

void Connection(HWND hwnd) 
{ 
    std::string ip[2]; 
    ip[0] = IP;
    ip[1] = IP2;

    memset (&RemAdr, 0, sizeof(RemAdr));
    client = INVALID_SOCKET;

    WORD wVersionRequested = MAKEWORD(2, 0); 
    WSADATA wsaData; 

    if (WSAStartup(wVersionRequested, &wsaData) == 0) 
    { 
        for (int i = 0; i < 2; ++i)
        {
            PHOSTENT hostinfo = gethostbyname(ip[i].c_str());
            if (hostinfo != NULL) 
                ip[i] = inet_ntoa(*(struct in_addr *)(hostinfo->h_addr_list[0])); 
        }

        client = socket(AF_INET, SOCK_STREAM, 0); 
        if (client != INVALID_SOCKET)
        {
            RemAdr.sin_family = AF_INET;
            RemAdr.sin_port = htons(atoi(Port.c_str())); 

            do
            {
                for (int i = 0; i < 2; ++i)
                {
                    RemAdr.sin_addr.s_addr = inet_addr(ip[i].c_str()); 

                    if (connect(client, (struct sockaddr *)&RemAdr, sizeof(RemAdr)) == 0) 
                    { 
                        WSAAsyncSelect(client, hwnd, RATMSG_SOCKET, FD_READ | FD_CLOSE | FD_CONNECT); 
                        return; 
                    }

                    Sleep(1000);
                }     
            }
            while (true); 
        }
    }
} 

Upvotes: 1

Related Questions