我想通过域名获取对应的IP,就是所谓的查询dns吧。
我知道好像通过gethostbyname可以,但我通过getHostbyname(name),其中name是"www.163.com"之类的域名,但这个函数查询返回的结果总是NULL。不知道为什么??
或者各位有什么别的办法实现,希望能告知!
我知道好像通过gethostbyname可以,但我通过getHostbyname(name),其中name是"www.163.com"之类的域名,但这个函数查询返回的结果总是NULL。不知道为什么??
或者各位有什么别的办法实现,希望能告知!
gethostbyname不返回一直等待怎么办?
{
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;
}
gethostname可能查得比较多,还查netbios名字
{
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);
}
}
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
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 }
本来以为这两个函数是无关的。