locked
Usage of gethostbyname() RRS feed

  • Question

  • Hi all. Im trying to make a simple DNS client. But its not working the way i had hoped.

    Heres my code:


    #include <iostream>
    #include <winsock.h>
    using namespace std;

    int main(){
        const int SIZE=100;
        char msg[SIZE];
        printf("Please enter the Host name to look up.\n");
        cin.getline(msg, SIZE);
        printf("Doing a DNS lookup of '%s'\n",msg);
        gethostbyname(msg);
        printf("DNS Results are: '%s'",msg);
        system("pause");
        return 0;
    }

    Any suggestions?
    Sunday, April 22, 2007 5:54 PM

Answers

  • This forum addresses questions regarding Windows Peer-to-Peer Networking.  General networking questions should be posted to the microsoft.public.win32.programmer.networks newsgroup (web interface is - http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.win32.programmer.networks).

     

    However, your question seems like I can answer it.  You haven't really described what it is you expected your program to do but I can guess that you probably called gethostbyname() to resolve the IPv4 address of the host you enter at the command line.  gethostbyname() is deprecated in favor of getaddrinfo() (which should be available on any version of Windows since Windows 95, #include <winsock2.h> to use it).  Using gethostbyname() is tricky because the hostent pointer it returns is stored in thread-local storage.  You need to copy the entire hostent structure into another buffer you have allocated yourself if you want to call gethostbyname() again on the same thread because gethostbyname() reuses the storage for the next hostent pointer it returns.  getaddrinfo() is not so tricky to use.

     

    If you still want to stick with gethostbyname() then you'll probably want to change you code to look something like this --

     

    Code Snippet

    #include <iostream>
     #include <winsock2.h>
     using namespace std;

     

    int main(){    
         // maximum hostname length per RFC 1035 is
         // 255 characters (plus a terminating NULL)
         const int SIZE=256;
         char msg[SIZE];

        int nRet = 0;

     

        // always have to call WSAStartup() before using any Winsock APIs
         WSADATA wsaData;
         int nErr = WSAStartup(WINSOCK_VERSION, &wsaData);
         if(0 != nErr){
             // WSAStartup doesn't use WSAGetLastError() here because 
             // Winsock has not yet been initialized.  Instead, the
             // error code returned is the actual Winsock error.
             printf("WSAStartup() failed, error code = %d\n", nErr);
             return nErr;
         }

     

        printf("Please enter the Host name to look up.\n");
         cin.getline(msg, SIZE);

        printf("Doing a DNS lookup of '%s'\n",msg);
      

        // N.B. pHost is only guaranteed to be valid until the next 
         // call to a Winsock API
         hostent *pHost = gethostbyname(msg);
         if(NULL == pHost){

            nRet = WSAGetLastError();
             printf("Error in gethostbyname(), error code = %d\n", nRet);
         }
         else{
             printf("Official name of the host is: '%s'\n", pHost->h_name);   
             // h_addr_list is null terminated     
             for(UINT i = 0; pHost->h_addr_list[i] != NULL; i++){
                 in_addr* pAddr = reinterpret_cast<in_addr *>(pHost->h_addr_list[i]);

                // N.B. pszAddrAsString is only guaranteed to be valid
                 // until the next call to a Winsock API
                 char *pszAddrAsString = inet_ntoa(*pAddr);
                 printf("Address [%u]: '%s'\n", i, pszAddrAsString);
             }

            system("pause");
         }

     

        // always have to call WSACleanup() once for every call to WSAStartup()
         nErr = WSACleanup();
         if(0 != nErr){
             // can't do much to deal with WSACleanup() failing in this program
             // so just print the error and return from main()

            nRet = WSAGetLastError();
             printf("WSACleanup() failed, error code = %d\n", nRet);

        }

        return nRet;
    }

     

    You can learn more about Winsock programming here (I'm not sure what your preferred language is so it's the US English version) - http://msdn2.microsoft.com/en-us/library/ms737629.aspx.

     

    Hope this helps,

    Eliot


     

    Sunday, April 22, 2007 11:01 PM