2012-04-24 17 views
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アドレスを持つ方法を作ることを試みていました。したがって、127.0.0.1に接続できない場合は、次に127.0.0.2を試し、次に127.0.0.1に戻ってexmapleを実行してください。それをどうすれば管理できますか?

P.S.私のコードで "悪い習慣"のように見えるものは何かを指摘してください。私は将来それを学び/修正することができます。ありがとう。

答えて

1

ハンドルリークがあります。最初のconnect()が失敗した場合は、socket()を呼び出して新しいSOCKETハンドルを割り当てて、同じclientに割り当てると、前に割り当てたSOCKETが失われます。 connect()への2回目の呼び出しが失敗した場合、ループはsocket()を再度呼び出して、同じclient変数に再度割り当てます。何度も何度も何度も何度も何度も何度も繰り返し実行します。それは時間の経過とともに資源を無駄にすることになります。あなたは余分なsocket()呼び出しを取り除く必要があります。ループに入る前にsocket()に一度だけ電話をかけてから、既存のSOCKETを使用して各IPに対してループコールconnect()を呼び出してください。

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

感謝の男:

編集は、より多くのこのような何かを試してみてください! + rep! – user1348950

+0

いいえ、ループの外にいる必要があります。ループ内には 'connect()'だけが必要です。 –

+0

onyl connectがループ内にある場合どのように私はそれが使用するipを変更するのですか? – user1348950

関連する問題