tags:

views:

451

answers:

5

How can I resolve a host IP address, given a URL in Visual C++?

A: 

gethostbyname?

aaa
`getaddrinfo` ?
asveikau
A: 

Parse the URL to get the host name. Then call gethostbyname or the corresponding API on your platform to get the IP address(es). If you are parsing a HTTP header, look for the HostName header to determine the host name.

Permaquid
A: 
struct hostent *he;

if ((he = gethostbyname("localhost") == NULL) {
    // Handle error: Failed
}

The IP address will be in he->h_addr. Works on both windows, linux and most likely macos.

Andreas Bonini
I'm not getting anything, just an "expression cannot be evaluated" for both localhost and for example, http://www.stackoverflow.com. Bare with me as I'm not a C++ engineer, only learning. If I remove the if statement, and simply assign gethostname to he, with the URL, nothing seems to happen.
George
+2  A: 

To use the socket functions under Windows, you have to start by calling WSAStartup, specifying the version of Winsock you want (for your purposes, 1.1 will work fine). Then you can call gethostbyname to get the address of the host. When you're done, you're supposed to call WSACleanup. Putting that all together, you get something like this:

#include <windows.h>
#include <winsock.h>
#include <iostream>
#include <iterator>
#include <exception>
#include <algorithm>
#include <iomanip>

class use_WSA { 
    WSADATA d; 
    WORD ver;
public:
    use_WSA() : ver(MAKEWORD(1,1)) { 
        if ((WSAStartup(ver, &d)!=0) || (ver != d.wVersion))
            throw(std::runtime_error("Error starting Winsock"));
    }
    ~use_WSA() { WSACleanup(); }    
};

int main(int argc, char **argv) {
    if ( argc < 2 ) {
        std::cerr << "Usage: resolve <hostname>";
        return EXIT_FAILURE;
    }

    try { 
        use_WSA x;

        hostent *h = gethostbyname(argv[1]);
        unsigned char *addr = reinterpret_cast<unsigned char *>(h->h_addr_list[0]);
        std::copy(addr, addr+4, std::ostream_iterator<unsigned int>(std::cout, "."));
    }
    catch (std::exception const &exc) {
        std::cerr << exc.what() << "\n";
        return EXIT_FAILURE;
    }

    return 0;
}

Edit: removed code to set the base to 16 -- IP addresses are usually printed in decimal.

Jerry Coffin
+1  A: 
dreamlax
When compiling on Windows, use `cl resolve.c /link ws2_32.lib` or else you will get some undefined symbol errors when linking.
dreamlax
Hah! On Windows, if the name was not found, for some reason it `h_errno` contains `NO_ADDRESS` instead of `HOST_NOT_FOUND`.
dreamlax
`gethostbyname` has been superseded by `getaddrinfo`. Static buffers? IPV4 only? Join the 21st century! :P
asveikau