1
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アドレスが失敗した場合に接続するための「バックアップ」IPアドレスを持つ方法を作ろうとしていました。したがって、127.0.0.1に接続できない場合は、次に127.0.0.2を試してから、例として127.0.0.1に戻ってください。どうすればそれを管理できますか?

PSあなたが私のコードで「悪い習慣」のように見えるものは何でも、私が将来それを学び/修正できるようにそれを指摘してください。ありがとう。

4

1 に答える 1

1

ハンドルリークがあります。最初の処理connect()が失敗した場合はsocket()、新しいSOCKETハンドルを割り当てて同じclient変数に割り当てているため、SOCKET以前に割り当てたハンドルが失われます。への 2 回目の呼び出しがconnect()失敗した場合、ループは再度呼び出して同じ変数にsocket()割り当てます。それは時間の経過とともにリソースを浪費することになります。余分な呼び出しを取り除く必要があります。ループに入る前に 1 回だけ呼び出してから、既存の IP を使用して各 IP に対してループ呼び出しを行います。clientconnect()socket()socket()connect()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); 
        }
    }
} 
于 2012-04-24T04:08:55.007 に答える