使用htonl()使用C ++正确转换localhost

时间:2016-09-12 23:40:09

标签: c++

我有如下定义:

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

如果我将1.0.0.127打印到stdout,我会看到src.sin_addr.s_addr,这似乎是错误的排序。

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

3 个答案:

答案 0 :(得分:6)

十进制的

2130706433是十六进制的0x7f000001,因此网络字节顺序已经是127.0.0.1。

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

答案 1 :(得分:4)

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

src.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

答案 2 :(得分:0)

如果您的主机订单与净订单匹配(或不符合),则宏通常不执行任何操作(或所有正确的操作)。

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

目标是便携性。始终使用宏使代码更具可移植性,并使程序员(或代码阅读器)无需知道主机的顺序。

示例:以digi-dot形式和十六进制网络顺序报告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);
}