How can I resolve a host IP address, given a URL in Visual C++?
问题:
回答1:
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.
回答2:
I'm not sure if there is a specific C++ class to do host name lookups, but you can always resort to plain C for such things. Here's my version which compiles and runs on Linux, Mac OS X, and Windows.
#include <stdio.h> #ifdef _WIN32 # include "winsock.h" #else # include <netdb.h> # include <arpa/inet.h> #endif static void initialise(void) { #ifdef _WIN32 WSADATA data; if (WSAStartup (MAKEWORD(1, 1), &data) != 0) { fputs ("Could not initialise Winsock.\n", stderr); exit (1); } #endif } static void uninitialise (void) { #ifdef _WIN32 WSACleanup (); #endif } int main (int argc, char *argv[]) { struct hostent *he; if (argc == 1) return -1; initialise(); he = gethostbyname (argv[1]); if (he == NULL) { switch (h_errno) { case HOST_NOT_FOUND: fputs ("The host was not found.\n", stderr); break; case NO_ADDRESS: fputs ("The name is valid but it has no address.\n", stderr); break; case NO_RECOVERY: fputs ("A non-recoverable name server error occurred.\n", stderr); break; case TRY_AGAIN: fputs ("The name server is temporarily unavailable.", stderr); break; } } else { puts (inet_ntoa (*((struct in_addr *) he->h_addr_list[0]))); } uninitialise (); return he != NULL; }
Once compiled, provide the host name as an argument:
$ ./a.out stackoverflow.com 69.59.196.211
回答3:
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.
回答4:
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.
回答5:
gethostbyname
?