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