gethostbyname - h_addr_list错误的第一位

时间:2014-10-14 16:21:18

标签: c gethostbyname

正如标题所述,我从gethostbyname回来的数据似乎有一个错误的第一位。

这是一个简短的例子:

struct hostent* host=  gethostbyname("indiana.cs.rit.edu");

if (!host)
    exit(-1);


printf("%d.%d.%d.%d\n", (host->h_addr_list[0][0]),
                        (host->h_addr_list[0][1]),
                        (host->h_addr_list[0][2]),
                        (host->h_addr_list[0][3]));


printf("%d.%d.%d.%d\n",UP(host->h_addr_list[0][0]),
                       UP(host->h_addr_list[0][1]),
                       UP(host->h_addr_list[0][2]),
                       UP(host->h_addr_list[0][3]));

UP定义为

#define UP(X) (((int)X) & 0XFF)

上述代码的输出是:

-127.21.37.10129.21.37.10

现在我知道我应该使用inet_ntoa获取我的char *版本的IP地址。但是,有谁知道为什么我的第一个字节被破坏了?由于我从host->h_addr_list返回char **,我的第一个[]应该尊重第一个地址,其中第二个[]应该取消引用实际的char。假设char是1byte,为什么我必须执行按位运算符来清除损坏的位?

增加混乱的层次是我得到-127或129的原因。

例如,在二进制中,我的129对于一个字节应该看起来像..

1000 0001

但是,基于-127的值,它表明我的基础二进制值是。

1111 1111

现在,我真的感到困惑的是0XFF(1111 1111)的按位运算符如何返回129,因为我看到它应该返回255表示无符号或-127表示签名。额外数据来自哪里?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

当你使用%d时,

host->h_addr_list[0][0]会将符号扩展为有符号的int。

如果你这样做:

printf("%d.%d.%d.%d\n", (unsigned char)(host->h_addr_list[0][0]),
                        (unsigned char)(host->h_addr_list[0][1]),
                        (unsigned char)(host->h_addr_list[0][2]),
                        (unsigned char)(host->h_addr_list[0][3]));

然后你就不会有问题了。

在二进制补码(8位)129和-127具有相同的位模式并且您的分析错误。

11111111在8位有符号二进制补码(不是-127)中为-1,有符号8位数的范围为-128到127.

1000000 = -128  (128 unsigned)
1000001 = -127  (129 unsigned)
1000010 = -126  (130 unsigned) (etc)