簡體   English   中英

C++ 從 URL 解析主機 IP 地址

[英]C++ Resolve a host IP address from a URL

給定Visual C++ 中的 URL,如何解析主機 IP 地址?

我不確定是否有一個特定的 C++ 類來進行主機名查找,但是您總是可以使用純 C 來處理這些事情。 這是我在 Linux、Mac OS X 和 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;
}

編譯后,提供主機名作為參數:

$ ./a.out stackoverflow.com
69.59.196.211

要在 Windows 下使用套接字函數,您必須首先調用WSAStartup ,指定所需的 Winsock 版本(對於您的目的,1.1 可以正常工作)。 然后就可以調用gethostbyname來獲取主機地址了。 完成后,您應該調用 WSACleanup。 把所有這些放在一起,你會得到這樣的東西:

#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;
}

簡單如下:

Linux 上

#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>
int main()
{
struct hostent *he=gethostbyname("www.stackoverflow.com");
char *ip=inet_ntoa(*(struct in_addr*)he->h_addr_list[0]);
printf(ip);
}

Windows 上

#include <stdio.h>
#include <winsock.h>
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
struct hostent *he=gethostbyname("www.stackoverflow.com");
char *ip=inet_ntoa(*(struct in_addr*)he->h_addr_list[0]);
printf(ip);
}

安卓上

#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main()
{
struct hostent *he=gethostbyname("www.stackoverflow.com");
char *ip=inet_ntoa(*(struct in_addr*)he->h_addr_list[0]);
printf(ip);
}

為Android編譯

在 arch-arm 上使用這些標志: -Wl,-s -lz -rdynamic -fPIE -pie

完成后,通過adb運行它

adb push <binfile> /data/local/tmp

adb shell /data/local/tmp/<binfile>

解析 URL 以獲取主機名。 然后在您的平台上調用 gethostbyname 或相應的 API 以獲取 IP 地址。 如果您正在解析 HTTP 標頭,請查找 HostName 標頭以確定主機名。

struct hostent *he;

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

IP 地址將在he->h_addr 適用於 Windows、Linux 和最有可能的 macos。

gethostbyname

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM