我想通过域名获取对应的IP,就是所谓的查询dns吧。
我知道好像通过gethostbyname可以,但我通过getHostbyname(name),其中name是"www.163.com"之类的域名,但这个函数查询返回的结果总是NULL。不知道为什么??
或者各位有什么别的办法实现,希望能告知!

解决方案 »

  1.   

    ::WSAGetLastError()。看看返回值是多少。
      

  2.   

    sevencat(七猫) :
    gethostbyname不返回一直等待怎么办?
      

  3.   

    一定会返回的,不返回的话系统就有问题了。假如是基于窗口的程序的话,还有一个WSAAsyncGetHostByName函数可以用用。
      

  4.   

    我曾经写过一个查IP和反查IP的,就用的这个函数(只有13.5K),不过原代码被我误删掉了。现在又不高兴再写。
      

  5.   

    不会成功吧!dns和hostname是有差别的哦
      

  6.   

    DWORD CSiyuMUDlg::GetServerIP()
    {
    DWORD dwIP = 0;;
    CString strHostName="www.163.com";
    WORD wVersionRequested = MAKEWORD(2, 2);
    WSADATA wsaData;
    if (WSAStartup(wVersionRequested, &wsaData) != 0) return 0; HOSTENT *pHS = gethostbyname( strHostName.GetBuffer(strHostName.GetLength()) );
    if( pHS != NULL)
    {
    in_addr addr;
    CopyMemory(&addr.S_un.S_addr, pHS->h_addr_list[0], pHS->h_length);
    dwIP = addr.S_un.S_addr;
    }
    WSACleanup();
    return dwIP;
    }
      

  7.   

    dns查得比gethostname范围广,不但能查这类地址,还能查诸如邮件之类的地址。
    gethostname可能查得比较多,还查netbios名字
      

  8.   

    void gethostip()
    {
    printf("获得主机名...");
    char hostname[128];
    if(gethostname (hostname,128)==SOCKET_ERROR)
    {
    printf("失败!\n");
    return;
    }
    else
    printf("OK\n");
    if(WSAGetLastError()==WSANOTINITIALISED)
    Beep(1000,100);
    hostent *host=gethostbyname(hostname);
    printf("获得主机IP地址...");
    if(host==NULL)
    {
    printf("失败!\n");
    return;
    }
    char *ip;
    in_addr in;
    for(int i=0;host->h_addr_list[i]!=NULL;i++)
    {
    memmove(&in,host->h_addr_list[i],4);
    ip=inet_ntoa(in);
    printf("主机的IP地址为:%s\n",ip);
    }
    }
      

  9.   

    闭来无事,把WINSOCK2。DLL的这个函数实现贴出来
    00246 struct hostent FAR * WSAAPI
    00247 gethostbyname(
    00248     IN const char FAR * name
    00249     )
    00250 /*++
    00251 Routine Description:
    00252 
    00253     Get host information corresponding to a hostname.
    00254 
    00255 Arguments:
    00256 
    00257     name - A pointer to the null terminated name of the host.
    00258 
    00259 Returns:
    00260 
    00261     If  no  error  occurs,  gethostbyname()  returns  a  pointer to the hostent
    00262     structure  described  above.   Otherwise  it  returns  a NULL pointer and a
    00263     specific errorr code is stored with SetErrorCode().
    00264 --*/
    00265 {
    00266     struct hostent * hent;
    00267     LPBLOB pBlob;
    00268     PCHAR pResults;
    00269     CHAR localResults[RNR_BUFFER_SIZE];
    00270     INT ErrorCode;
    00271     PDPROCESS Process;
    00272     PDTHREAD Thread;
    00273     CHAR  szLocalName[200];   // for storing the local name. This
    00274                               // is simply a big number assumed
    00275                               // to be large enough. This is used
    00276                               // only when the caller chooses not to
    00277                               // provide a name. Very lazy.
    00278     PCHAR pszName;
    00279 
    00280     ErrorCode = PROLOG(&Process,
    00281                  &Thread);
    00282     if(ErrorCode != ERROR_SUCCESS)
    00283     {
    00284         SetLastError(ErrorCode);
    00285         return(NULL);
    00286     }
    00287 
    00288     //
    00289     // A NULL input name means look for the local name. So,
    00290     // get it.
    00291     //
    00292     if(!name || !*name)
    00293     {
    00294         if(gethostname(szLocalName, 200) != NO_ERROR)
    00295         {
    00296             return(NULL);
    00297         }
    00298         pszName = szLocalName;
    00299     }
    00300     else
    00301     {
    00302         pszName = (PCHAR)name;
    00303     }
    00304 
    00305     pResults = localResults;
    00306 
    00307     pBlob = getxyDataEnt( &pResults,
    00308                           RNR_BUFFER_SIZE,
    00309                           pszName,
    00310                           &HostAddrByNameGuid,
    00311                           0);
    00312 
    00313     if ( !pBlob &&
    00314          ( !name || !*name ) )
    00315     {
    00316         pBlob = getxyDataEnt( &pResults,
    00317                               RNR_BUFFER_SIZE,
    00318                               NULL,
    00319                               &HostAddrByNameGuid,
    00320                               0);
    00321     }
    00322 
    00323     if(pBlob)
    00324     {
    00325         hent = (struct hostent *)Thread->CopyHostEnt(pBlob);
    00326         if(hent)
    00327         {
    00328             UnpackHostEnt(hent);
    00329         }
    00330     }
    00331     else
    00332     {
    00333         hent = 0;
    00334 
    00335         if(GetLastError() == WSASERVICE_NOT_FOUND)
    00336         {
    00337             SetLastError(WSAHOST_NOT_FOUND);
    00338         }
    00339     }
    00340 
    00341     if (pResults!=localResults)
    00342         delete pResults;
    00343 #ifdef RASAUTODIAL
    00344     //
    00345     // Inform Autodial of a successful name lookup.
    00346     // This is important with DNS, since reverse lookups
    00347     // do not provide complete information about name
    00348     // aliases.
    00349     //
    00350     if (hent)
    00351         WSNoteSuccessfulHostentLookup(name, *(PULONG)hent->h_addr);
    00352 #endif // RASAUTODIAL
    00353     return(hent);
    00354 }  // gethostbyname
      

  10.   

    00679 //
    00680 // The protocol restrictions list for all emulation operations. This should
    00681 // limit the invoked providers to the set that know about hostents and
    00682 // servents. If not, then the special SVCID_INET GUIDs should take care
    00683 // of the remainder.
    00684 //
    00685 AFPROTOCOLS afp[2] = {
    00686                       {AF_INET, IPPROTO_UDP},
    00687                       {AF_INET, IPPROTO_TCP}
    00688                      };
    00689 
    00690 LPBLOB
    00691 getxyDataEnt(
    00692     IN OUT PCHAR *pResults,
    00693     IN     DWORD dwLength,
    00694     IN     LPSTR lpszName,
    00695     IN     LPGUID lpType,
    00696     OUT    LPSTR *  lppName OPTIONAL
    00697     )
    00698 {
    00699 
    00700 /*++
    00701 Routine Description:
    00702    See comment above for details
    00703 --*/
    00704 
    00705     PWSAQUERYSETA pwsaq = (PWSAQUERYSETA)*pResults;
    00706     int err;
    00707     HANDLE hRnR;
    00708     LPBLOB pvRet = 0;
    00709     INT Err = 0;
    00710     DWORD origLength = dwLength; // Safe the length of the original buffer
    00711                                  // in case we need to reallocate it.
    00712 
    00713     if ( lppName )
    00714     {
    00715         *lppName = NULL;
    00716     }
    00717 
    00718     //
    00719     // create the query
    00720     //
    00721     memset(pwsaq, 0, sizeof(*pwsaq));
    00722     pwsaq->dwSize = sizeof(*pwsaq);
    00723     pwsaq->lpszServiceInstanceName = lpszName;
    00724     pwsaq->lpServiceClassId = lpType;
    00725     pwsaq->dwNameSpace = NS_ALL;
    00726     pwsaq->dwNumberOfProtocols = 2;
    00727     pwsaq->lpafpProtocols = &afp[0];
    00728 
    00729     err = WSALookupServiceBeginA(pwsaq,
    00730                                  LUP_RETURN_BLOB | LUP_RETURN_NAME,
    00731                                  &hRnR);
    00732 
    00733     if(err == NO_ERROR)
    00734     {
    00735 
    00736         //
    00737         // If the original buffer is small to contain the results
    00738         // will allocate new one and retry the call.
    00739         //
    00740     Retry:
    00741 
    00742         //
    00743         // The query was accepted, so execute it via the Next call.
    00744         //
    00745         err = WSALookupServiceNextA(
    00746                                 hRnR,
    00747                                 0,
    00748                                 &dwLength,
    00749                                 pwsaq);
    00750         //
    00751         // if NO_ERROR was returned and a BLOB is present, this
    00752         // worked, just return the requested information. Otherwise,
    00753         // invent an error or capture the transmitted one.
    00754         //
    00755 
    00756         if(err == NO_ERROR)
    00757         {
    00758             if(pvRet = pwsaq->lpBlob)
    00759             {
    00760                 if(lppName)
    00761                 {
    00762                     *lppName = pwsaq->lpszServiceInstanceName;
    00763                 }
    00764             }
    00765             else
    00766             {
    00767                 if ( lpType == &HostNameGuid )
    00768                 {
    00769                     if(lppName)
    00770                     {
    00771                         *lppName = pwsaq->lpszServiceInstanceName;
    00772                     }
    00773                 }
    00774                 else
    00775                 {
    00776                     err = WSANO_DATA;
    00777                 }
    00778             }
    00779         }
    00780         else
    00781         {
    00782             //
    00783             // WSALookupServiceEnd clobbers LastError so save
    00784             // it before closing the handle.
    00785             //
    00786 
    00787             err = GetLastError();
    00788 
    00789             //
    00790             // The provider returns WSAEFAULT if the result buffer
    00791             // is not large enough (to make sure that this is not
    00792             // just a random error or a result AV when accessing the
    00793             // the buffer content, we check the returned buffer size
    00794             // against the value that we initially supplied).
    00795             //
    00796             if ((err==WSAEFAULT) && (dwLength>origLength))
    00797             {
    00798                 PCHAR   newBuffer = new CHAR[dwLength];
    00799                 if (newBuffer)
    00800                 {
    00801                     //
    00802                     // Remeber the new length, so that provider cannot
    00803                     // force us to loop indefinitely (well if it keeps
    00804                     // increasing required buffer size, we'll run into
    00805                     // out of memory error sometimes).
    00806                     // 
    00807                     origLength = dwLength;
    00808 
    00809                     //
    00810                     // Replace the callers pointer to the buffer, so
    00811                     // it knows to free it
    00812                     //
    00813                     *pResults = newBuffer;
    00814 
    00815                     //
    00816                     // Repoint results to new buffer.
    00817                     //
    00818                     pwsaq = (PWSAQUERYSETA)newBuffer;
    00819                     
    00820                     //
    00821                     // Try the Next call again.
    00822                     //
    00823                     goto Retry;
    00824                 }
    00825                 else 
    00826                 {
    00827                     err = WSA_NOT_ENOUGH_MEMORY;
    00828                 }
    00829             }
    00830         }
    00831         WSALookupServiceEnd(hRnR);
    00832 
    00833         //
    00834         // if an error happened, stash the value in LastError
    00835         //
    00836 
    00837         if(err != NO_ERROR)
    00838         {
    00839             SetLastError(err);
    00840         }
    00841     }
    00842     return(pvRet);
    00843 }
      

  11.   

    知道原因了,主要是没先调用WSAStartup()就直接调用gethostbyname()
    本来以为这两个函数是无关的。