【问题标题】:How to replace inet_pton with getaddrinfo如何用 getaddrinfo 替换 inet_pton
【发布时间】:2019-11-27 15:40:50
【问题描述】:

考虑 inet_pton 函数:

#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst)

据我了解,该函数以点分十进制形式的IP地址字符串作为输入(src)并将该字符串转换为字节形式,这是某些网络编程任务所需要的。事实上,src 被转换为一个结构 in_addr,它被复制到 dst(假设 af = AF_INET)。在这个结构中,应该有一个字节形式的 IP 地址条目(如果我错了,请纠正我!)。

我希望能够使用 inet_pton,但我不想以点分十进制形式提供 src,而是想提供一个可以由我的 DNS 服务器解析的名称。

示例: 而不是inet_pton(AF_INET, "10.70.1.114", buf) 我想使用inet_pton(AF_INET, "myPC", buf)

我在想,也许我可以在之前使用getaddrinfogetnameinfo 来解析我的名字。我在想这样一个函数:

char* resolvename(const char* name)
{
    struct addrinfo *infoptr, hints;
    char host[256];

    hints.ai_family=AF_INET;
    int result = getaddrinfo(name,NULL,&hints,&infoptr);
    if(result){
        fprintf(stderr, "getaddrinfo: %s\n", gai_stderror(result));
        exit(1);
        }
    getnameinfo(infoptr->ai_addr, infoptr->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);

    return host; 

}

我应该可以这样做:

mySrc = resolvename("myPC");
inet_pton(AF_INET, mySrc, buf);

这有任何意义吗?只是说:我没有任何网络编程经验。所有这些功能对我来说都很新,所以请赐教!

【问题讨论】:

  • 您确定要询问 C++ 而不是 C?因为它看起来更像 C 而不是 C++。
  • getaddrinfo 已经为您提供了 IP 地址。目前尚不清楚通过将其转换为char 字符串,然后通过inet_pton 立即返回到相同的确切IP 地址,您期望完成什么。这就像打印一封电子邮件,在木桌上扫描,然后转发附件。
  • @SamVarshavchik:我遇到了使用 inet_pton 的代码:if (inet_pton(AF_INET, split[9].c_str(), buf)) {。所以,split[9].c_str() 是从文件中读取的一些字符串。而这个字符串 - 以现在的代码方式 - 需要是一个点分十进制形式的 IP。但我希望这个字符串是“myPC”。当它是“myPC”并且我运行我的问题中给出的代码时,这在理论上可行吗?
  • 你错过了我的意思。你不需要“myPC”,你已经有了来自getaddrinfo()的myPC的IP地址。
  • 哦,我明白了。感谢您指出这一点!

标签: c++ sockets network-programming


【解决方案1】:
char host[256];
...
return host; 

您返回指向自动数组的指针。该数组在作用域结束时自动销毁,因此您返回一个悬空指针。通过悬空指针间接的行为是未定义的。

此外,如果调用 freeaddrinfo 失败,您会泄漏内存。

getaddrinfo 返回sockaddr 的列表,其中已经包含字节形式的 IP。如何取出它的示例:

for (; infoptr; infoptr = infoptr->ai_next) {
    if (infoptr->ai_family == AF_INET) {
        assert(infoptr->ai_addrlen == sizeof(sockaddr_in));
        sockaddr_in addr;
        std::memcpy(&addr, infoptr->ai_addr, sizeof addr);
        std::memcpy(buf, addr.sin_addr, sizeof addr.sin_addr);
        break;
    }
}

如果你很聪明,理论上可能有一种方法可以使用 offsetof 来摆脱中间的 memcpy 到本地 sockaddr_in

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-05
    • 2015-11-12
    • 2023-03-24
    • 1970-01-01
    • 2021-08-18
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多