主机字节序
不同的CPU有不同的字节序类型,这些字节序是指 整数 在内存中保存的顺序,这个叫做 主机序。
最常见的有两种: 大端和小端
1.Little endian:将低序字节存储在起始地址
2.Big endian:将高序字节存储在起始地址
主机序大小端的地址存放方式
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
网络字节序
网络与主机字节转换函数:htons()、ntohs()、htonl()、ntohl() (注意:s 就是short l是long h是host n是network),并且以大端字节序为主
in_addr_t inet_addr(const char* strptr);
字符串有效则将字符串转换为32位二进制网络字节序的IPV4地址
例如:inet_addr(“127.0.0.1”);
其实就是将点分十进制转化成转换成长整型的数字
uint32_t htonl(uint32_t hostlong);
例如:htonl(2130706433);
将点分十进制转化成转换成长整型的数字
inet_ntoa()作用是将一个sin_addr结构体输出成IP字符串(network to ascii),注意不要在同一个printf语句中操作两个inet_ntoa,会出现问题
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
int main(int argc, char *argv[])
{
struct in_addr addr1,addr2;
ulong l1,l2;
l1= inet_addr("192.168.0.74");
l2 = inet_addr("211.100.21.179");
memcpy(&addr1, &l1, 4);
memcpy(&addr2, &l2, 4);
printf("%s : %s\n", inet_ntoa(addr1), inet_ntoa(addr2)); //注意这一句的运行结果
printf("%s\n", inet_ntoa(addr1));
printf("%s\n", inet_ntoa(addr2));
return 0;
}
实际运行结果如下:
192.168.0.74 : 192.168.0.74 //从这里可以看出,printf里的inet_ntoa只运行了一次。
192.168.0.74
211.100.21.179
inet_ntoa返回一个char *,而这个char *的空间是在inet_ntoa里面静态分配的,所以inet_ntoa后面的调用会覆盖上一次的调用。第一句printf的结果只能说明在printf里面的可变参数的求值是从右到左的,仅此而已