循环套接字连接尝试最终会断开Internet连接

时间:2012-04-24 03:14:38

标签: c++ sockets winsock2

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

尝试连接并连接失败几个小时后,用户的互联网最终会断开连接,直到您关闭应用程序。什么似乎是问题?我认为我的代码有点草率,所以任何有用的提示都会很棒,很乐意学习。

在此我实际上试图让它有一个“备份”IP地址连接到第一个失败。因此,如果它无法连接到127.0.0.1,请尝试下一步127.0.0.2,然后返回127.0.0.1以获取exmaple。我该如何管理?

P.S。你在我的代码中看到的任何看起来像“坏习惯”的东西,请指出它,以便我将来可以学习/修复它。感谢。

1 个答案:

答案 0 :(得分:1)

你有手柄泄漏。如果第一个connect()失败,您正在呼叫socket()分配一个新的SOCKET句柄并将其分配给同一个client变量,从而失去您拥有的SOCKET先前已分配。如果对connect()的第二次调用失败,您的循环会再次调用socket()并再次将其分配给相同的client变量,并一次又一次地将其分配给connect()终于成功,如果有的话。随着时间的推移,这将浪费资源。你需要摆脱额外的socket()电话。在进入循环之前只调用socket()一次,然后使用现有的connect()为每个IP调用SOCKET

修改尝试更类似的内容:

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