0

正如标题所述,我从其中返回的数据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(有符号)。额外的数据来自哪里?

我在这里先向您的帮助表示感谢。

4

1 回答 1

1

host->h_addr_list[0][0]当您将 %d 与它一起使用时,将符号扩展为带符号的 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 位有符号二进制补码中是 -1(不是 -127),有符号 8 位数字的范围是 -128 到 127。

1000000 = -128  (128 unsigned)
1000001 = -127  (129 unsigned)
1000010 = -126  (130 unsigned) (etc)
于 2014-10-14T16:41:03.650 回答