之前在写网络程序时,基本都会发出去之前调用htons/htonl、接收端收到报文后按照ntohs/ntohl来反解析,只知道是为了处理不同机器架构大小端带来的问题,并未深入思考其中的逻辑,今天突然想到了这个,就查了下,竟然与自己一直以为的不一样!!
linux的源代码位于/include/netinet/in.h
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
so these functions are all just identity. */
# define ntohl(x) (x)
# define ntohs(x) (x)
# define htonl(x) (x)
# define htons(x) (x)
# else
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define ntohl(x) __bswap_32 (x)
# define ntohs(x) __bswap_16 (x)
# define htonl(x) __bswap_32 (x)
# define htons(x) __bswap_16 (x)
# endif
# endif
大吃一惊,原来是宏,如果平台是大端字序的(如MIPS架构),则这些函数不作任何转换,只有在平台是小端字序时(如X86、ARM),这些函数才进行相应的转换,htons和ntohs(以及htonl和ntohl)实际上没有任何区别,都是把字节序反转,只在于使用者对网络端和主机端理解意义的不同。