gethostbyname - неверный первый бит h_addr_list

Как видно из названия, данные, которые я получаю от 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.10 а также 129.21.37.10,

Теперь я знаю, что я должен использовать inet_ntoa чтобы получить мою char* версию IP-адреса. Однако кто-нибудь знает, почему мой первый байт искажен? Так как я получаю обратно символ ** от host->h_addr_list мой первый [] следует ссылаться на первый адрес, где второй [] следует разыменование к фактическому символу. учитывая, что символ равен 1 байту, почему я должен выполнить побитовый оператор, чтобы очистить искаженный бит?

Добавление к слою путаницы - вот почему я получаю -127 или 129.

Например, в двоичном коде мой 129 для одного байта должен выглядеть так:

1000 0001

Однако, исходя из значения -127, это говорит о том, что мое базовое двоичное значение равно.

1111 1111

Теперь, где я действительно запутался, это то, как побитовый оператор 0XFF (1111 1111) возвращает 129, поскольку, как я вижу, он должен возвращать 255 для неподписанного или -127 для подписанного. Откуда поступают дополнительные данные?

Спасибо за помощь заранее.

1 ответ

Решение

host->h_addr_list[0][0] становится расширенным знаком в подписанном int, когда вы используете%d с ним.

Если бы вы должны были сделать:

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 равен -1 в 8-битном дополнении со знаком 2 (не -127), а диапазон 8-битного числа со знаком составляет от -128 до 127.

1000000 = -128  (128 unsigned)
1000001 = -127  (129 unsigned)
1000010 = -126  (130 unsigned) (etc)
Другие вопросы по тегам