我有如下定义:
#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
,这似乎是错误的排序。
这样做的正确方法是什么?
答案 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);
}