所以我有一段代码基本上应该将u_int32(或hex)中给出的IP地址的第一个字节转换为char *。例如,如果 192.168.10.49 ( 0x31 0x0a 0xa8 0xc0 ),则应返回 192 ( 0xc0 )。 IP地址以网络字节顺序给出。我写了一段有用的代码,但是,我不明白它是如何工作的原因。
struct sockaddr_in *addr = (struct sockaddr_in *) malloc(sizeof(addr));
unsigned char *ip_str;
int i = 0;
/* cast sockaddr to sockaddr_in. ip is given as an argument of sockaddr */
addr = (struct sockaddr_in*) ip;
/* cast address */
ip_str = (char *) &(addr->sin_addr.s_addr);
printf("addr: %02x\n", addr->sin_addr.s_addr);
printf("ip_str: %02x\n", (int) (*ip_str));
在这段代码中,我给出了一个sockaddr结构,其中包含网络字节顺序的IP地址,然后我将其转换为sockaddr_in结构。最后,我将我的IP地址(u_int32格式)转换为char指针并获得 192 的结果(假设ip为 192.168.10.49 )。第一个printf函数以十六进制格式打印IP,其输出为:
310aa8c0
第二个,结果,打印为:
C0
但是,如果我从网络字节顺序转换为主机字节顺序(使用 ntohl()),我会得到以下结果:
c0a80a31
第二个打印出来:
31
我的问题是,这个演员如何运作?为什么要转换为IP地址的最后一个字节?欢迎任何有关此书或书籍参考的教程的链接。
答案 0 :(得分:1)
网络字节顺序是big-endian,显然你的主机字节顺序是little-endian。因此,使用ntohl
反转字节字符串。
请注意
printf("ip_str: %02x\n", (int) (*ip_str));
ip_str
是指向unsigned char
的指针。取消引用它会返回ip_str
中的第一个字节。
现在,您想知道为什么输出第一个字节而不是最后一个字节。这正是因为字节顺序。在内存中,您的四字节ip_str
采用小端格式,即最低有效字节存储为第一个。因此,如果您不是完整地访问那个四字节字符串而只访问第一个字节,那么实际上就是访问最后一个字节。