C++ 使用htonl()使用C++;

C++ 使用htonl()使用C++;,c++,C++,我有如下定义: #define LOCALHOST 2130706433 在中使用sockaddr\u时,我正在尝试更正网络/主机字节顺序: struct sockaddr_in src; src.sin_port = htons(0); src.sin_family = AF_INET; src.sin_addr.s_addr = htonl( LOCALHOST ); 如果我将src.sin\u addr.s\u addr打印到stdout,我会看到1.0.0.12

我有如下定义:

#define LOCALHOST            2130706433
在中使用
sockaddr\u时,我正在尝试更正网络/主机字节顺序:

struct sockaddr_in src;
src.sin_port = htons(0);
src.sin_family = AF_INET;
src.sin_addr.s_addr = htonl( LOCALHOST );
如果我将
src.sin\u addr.s\u addr
打印到stdout,我会看到
1.0.0.127
,这似乎顺序不正确


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

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


如果在英特尔x86平台上使用
htonl()
,由于x86是小端,因此
htonl()
最终会反转位。

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

src.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

如果主机顺序与净顺序匹配(或不匹配),宏通常不会执行任何操作(或执行所有正确的操作)

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

目标是可移植性。始终使用宏可以使代码更具可移植性,并使程序员(或代码读者)无需了解主机顺序


示例:以数字点形式和十六进制网络顺序报告_主机名

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;

相关的我必须质疑是谁编写了LOCALHOST define。对该常量使用十进制而不是十六进制是很奇怪的。htonl()(和其他)被设计为正确地“将多字节整数类型从主机字节顺序转换为网络字节顺序”。每一位主人。不管主机顺序如何。例如,如果您的主机顺序与网络顺序匹配,宏通常不会执行任何操作。换句话说,为什么对您不打算通过网络发送的数据使用
htonX
,而对您没有从网络接收的数据使用
ntohX
// ////////////////////////////////////////////////////////////////
// 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);
}