【问题标题】:Replacing gethostbyname to getaddrinfo for ICMP (IcmpSendEcho)将 gethostbyname 替换为 ICMP 的 getaddrinfo (IcmpSendEcho)
【发布时间】:2015-11-12 08:56:03
【问题描述】:

遗留代码有gethostbyname 来获取主机的IP 地址。然后将转换后的地址的整数部分传递给IcmpSendEcho。 我正在用getaddrinfo 替换这个过时的函数。

DWORD GetIPAddressInt(const char* pAddress)
{
    PADDRINFOA addr = nullptr;    
    addrinfo hints = { 0 };

    hints.ai_family = AF_INET;    
    // hints.ai_socktype = ??;
    // hints.ai_protocol = ??;
    getaddrinfo(pAddress, nullptr, &hints, &addr);

    auto sockaddr_ipv4 = reinterpret_cast<sockaddr_in*>(addr->ai_addr);

    return sockaddr_ipv4->sin_addr.S_un.S_addr;
}

我的问题是:ai_socktypeai_protocol 成员呢?

  • 套接字类型应该是SOCK_RAW 吗?
  • 协议应该是IPPROTO_ICMP(在标头中,而不是在 MSDN 中)?

再次重复,生成的 IP 地址将用于发送 ICMP 回显请求,因此我想知道是否需要 RAW/ICMP?目前,IPv6 不用担心。

【问题讨论】:

    标签: c++ windows winapi winsock2 icmp


    【解决方案1】:

    关于 getaddrinfo 的文档,您可以将此字段留空 (0)。

    ai_socktype 的值为零表示调用者将接受任何套接字类型。

    ai_protocol 的值为零表示调用者将接受任何协议。

    IPv4 和 IPv6 地址不取决于是用于流还是特定的协议类型。因此,调用IcmpSendEcho 只需忽略此字段即可。

    编辑:

    只有在指定了服务名称时,套接字类型和协议提示才可能相关。服务名称可以是“http”、“tftp”等。例如,如果指定“tftp”服务,则不能设置“流”套接字类型,因为 tftp 是基于数据报的。但在您的情况下(可能是大多数其他时间)服务字段保留为 NULL。例如,如果指定“http”服务,ai_addr.sin_port 中的端口成员也要填写。

    【讨论】:

    • 我在文档中阅读了该部分,但我对“任何”这个词感到困惑。这是否意味着getaddrinfo 将返回所有原型/套接字类型的 IP? getaddreinfo 可能应用的智能是什么?
    • @Ajay 由于 getaddrinfo 提供“从 ANSI 主机名到地址的独立于协议的转换”,并且由于 IPv4 地址不会因特定协议或套接字类型而改变,因此协议和套接字类型提示应该被忽略。但是,如文档中所述,我会将其设置为零(表示接受任何值),否则可能会返回 EAI_SOCKTYPE 之类的错误(未测试)。
    • @Ajay 您可以在 RFC 2553 中找到有关 getaddrinfo 实现的更多信息。
    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 2014-11-21
    • 2014-03-27
    • 1970-01-01
    • 2021-12-02
    • 2014-02-27
    相关资源
    最近更新 更多