Я пытаюсь устранить ошибку, из-за которой пытаюсь напечатать IP-адрес моей машины. На машине установлена ОС RedHat. Цель состоит в том, чтобы получить идентификатор хоста с помощью gethostid()
, а затем использовать функцию inet_ntoa
для преобразования его значения в строку.
Проблема в том, что результат показывает адрес в неправильном порядке. IP-адрес имеет следующий порядок a.b.c.d, но результат inet_ntoa
показывает его следующим образом b.a.d.c. Мне известно о проблеме с порядком байтов при использовании этих функций, но я думал, что из-за несоблюдения порядка байтов результатом будет обратный IP-адрес.
Я думаю, что проблема может быть в значении, возвращаемом gethostid()
. Но если это так, то я не уверен, почему мне выдается неправильный идентификатор.
Мой IP-адрес 172.30.223.27.
gethostid()
возвращает 514595807, что в шестнадцатеричном формате равно 1EAC1BDF, а затем преобразуется в байты 30.172.27.223.
#include <arpa/inet.h>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
int main() {
long hostId = gethostid();
std::cout << "Host ID: " << hostId << std::endl;
struct in_addr addr = inet_makeaddr(hostId,0 );
::std::string ipv4_addr_str = inet_ntoa(addr);
std::cout << "IP using inet_ntoa: " << ipv4_addr_str << std::endl;
char ipString[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr, ipString, INET_ADDRSTRLEN);
std::cout << "IP using using inet_ntop: " << ipString << std::endl;
return 0;
}
И результат:
Host ID: 514595807
IP using inet_ntoa: 30.172.27.223
IP using using inet_ntop: 30.172.27.223
Я пробовал использовать inet_ntoa
и inet_ntop
, чтобы проверить, возникает ли проблема в момент печати IP, но кажется, что проблема заключается в значении, полученном gethostid()
Почему это происходит?
Также обратите внимание, что gethostid на самом деле не возвращает IP-адрес. Он возвращает что-то похожее на IP-адрес, но не обязательно таковым.
Вместо этого вам следует использовать getifaddrs
, чтобы получить список сетевых адаптеров и перебрать их, чтобы получить IP-адреса.
Спасибо за ответ, я попробовал добавить преобразование с помощью <code>htonl</code>, но затем на выходе получилось 223.27.172.30, что является неправильным выводом раньше, но наоборот...
Спасибо за ответ, dbush, если этот подход с <code>gethostid()</code> не сработает, то я попробую получить IP из других источников, подобных тому, который вы предложили.
Как указано на связанной странице руководства, на самом деле возвращается не IP-адрес. Вы не можете полагаться на gethostid
, если хотите получить локальный IP-адрес.
Не пытайтесь использовать gethostid
в качестве IP-адреса; это просто не то, что есть.
Проверьте справочную страницу :
This normally resembles the Internet address for the local
machine, as returned by gethostbyname(3), and thus usually never
needs to be set.
...
In the glibc implementation, the hostid is stored in the file
/etc/hostid. (Before glibc 2.2, the file /var/adm/hostid was
used.)
In the glibc implementation, if gethostid() cannot open the file
containing the host ID, then it obtains the hostname using
gethostname(2), passes that hostname to gethostbyname_r(3) in
order to obtain the host's IPv4 address, and returns a value
obtained by bit-twiddling the IPv4 address. (This value may not
be unique.)
Обратите внимание на слово «обычно» в первом абзаце (означающее, что это может быть что-то совершенно несвязанное), на тот факт, что оно может быть установлено, и на «перестановку битов» в последнем абзаце.
Если вам нужен IP-адрес машины (их может быть несколько), используйте что-нибудь другое.
Похоже, вам нужно преобразовать число в сетевой порядок байтов (
hostid = htonl(hostid)
).