【问题标题】:using htonl() to properly convert localhost using C++使用 htonl() 使用 C++ 正确转换 localhost
【发布时间】:2016-09-12 23:40:08
【问题描述】:

我有如下定义:

#define LOCALHOST            2130706433

我正在尝试在使用 sockaddr_in 时更正网络/主机字节顺序:

struct sockaddr_in src;
src.sin_port = htons(0);
src.sin_family = AF_INET;
src.sin_addr.s_addr = htonl( LOCALHOST );

如果我将src.sin_addr.s_addr 打印到标准输出,我看到1.0.0.127 似乎订购不正确。

这样做的正确方法是什么?

【问题讨论】:

  • 我不得不质疑写 LOCALHOST 定义的人。对该常量使用十进制而不是十六进制简直是奇怪
  • htonl() (和其他)旨在正确“将多字节整数类型从主机字节顺序转换为网络字节顺序”。对于每个主机。无论主机顺序如何。例如,如果您的主机顺序与网络顺序匹配,宏通常什么都不做。

标签: c++


【解决方案1】:

十进制的2130706433是十六进制的0x7f000001,所以这已经是网络字节序的127.0.0.1了。

如果您在 Intel x86 平台上使用 htonl(),由于 x86 是 little-endian,htonl() 最终会反转位。

【讨论】:

  • 换句话说,为什么要使用htonX 来处理您不打算通过网络发送的数据,而使用ntohX 来处理您没有从网络接收到的数据?
【解决方案2】:

大多数平台都有一个INADDR_LOOPBACK 常量来表示 127.0.0.1。您应该使用该常量而不是定义自己的常量:

src.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

【讨论】:

    【解决方案3】:

    如果您的主机顺序与网络顺序匹配(或不匹配),宏通常什么都不做(或所有正确的事情)。

    换句话说,无论主机顺序如何,应用宏的位置在逻辑上都是相同的。

    目标是便携性。始终使用宏使代码更易于移植,并使程序员(或代码阅读器)无需了解主机顺序。


    示例:以数字点形式和十六进制网络顺序报告 a_hostname。

    std::cout << "a_hostname '" << a_hostname << "' maps to " 
              << target_host_digi_dot
              << " (" << std::hex << std::setfill('0') 
              << ntohl(ret_addr.sin_addr.s_addr) << ")" 
              << std::endl;
    

    类似的例子 -

    // ////////////////////////////////////////////////////////////////
    // returns previous sin_addr in Host Byte Order
    // sets sockaddr_in.sin_addr to Network Byte Order, digi-dot 
    //      is already NBO
    uint32_t DTB::SockaddrIn::setSinNboAddr(std::string 
                                            a_nboDigiDotHostnameStr)
    {
       //       hbo     = convert (nbo)
       uint32_t retVal = ntohl(sin_addr.s_addr);
       //
       int status = inet_aton(a_nboDigiDotHostnameStr.c_str(), &sin_addr);
    
       if(0 == status) // NOTE: 0 when failure! unusual
          throw(a_nboDigiDotHostnameStr);
    
       return (retVal);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      相关资源
      最近更新 更多