且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

通过 URL 获取 IP 地址

更新时间:2023-02-23 19:57:27

inet_addr() 接受 IPv4 地址字符串作为输入并返回该地址的二进制表示.在这种情况下,这不是您想要的,因为您没有 IP 地址,而是有一个主机名.

inet_addr() accepts an IPv4 address string as input and returns the binary representation of that address. That is not what you want in this situation, since you don't have a IP address, you have a hostname instead.

您使用 gethostby...() 走在正确的轨道上,但您需要使用 gethostbyname()(按主机名查找)而不是 gethostbyaddr()(按 IP 地址查找)1.而且您不能将完整的 URL 传递给其中任何一个.gethostbyname() 只接受一个主机名作为输入,所以你需要解析 URL 并提取它的主机名,然后你可以这样做:

You are on the right track by using gethostby...(), but you need to use gethostbyname() (lookup by hostname) instead of gethostbyaddr() (lookup by IP address) 1. And you cannot pass a full URL to either of them. gethostbyname() takes only a hostname as input, so you need to parse the URL and extract its hostname, and then you can do something like this:

const char host[] = ...; // an IP address or a hostname, like "www.google.com" by itself
target.sin_addr.s_addr = inet_addr(host);
if (target.sin_addr.s_addr == INADDR_NONE)
{
    struct hostent *phost = gethostbyname(host);
    if ((phost) && (phost->h_addrtype == AF_INET))
        target.sin_addr = *(in_addr*)(phost->h_addr);
    ...
}
else
    ...

1 顺便说一句,gethostby...() 函数已弃用,请使用 getaddrinfo()getnameinfo() 代替.

1 BTW, the gethostby...() functions are deprecated, use getaddrinfo() and getnameinfo() instead.

const char host[] = ...; // an IP address or a hostname, like "www.google.com" by itself

addrinfo hints = {0};
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

addrinfo *addr = NULL;

int ret = getaddrinfo(host, NULL, &hints, &addr);
if (ret == EAI_NONAME) // not an IP, retry as a hostname
{
    hints.ai_flags = 0;
    ret = getaddrinfo(host, NULL, &hints, &addr);
}
if (ret == 0)
{
    target = *(sockaddr_in*)(addr->ai_addr);
    freeaddrinfo(addr);
    ...
}
else
    ...