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)