#c #networking #cross-platform #byte #ip-address
#c #сеть #кроссплатформенный #байт #ip-адрес
Вопрос:
Каков наилучший способ получить ваш IP-адрес, а затем преобразовать его в байты с помощью C ? Мне нужно что-то кроссплатформенное. Я нашел много, но я не знаю, какой метод лучше.
Комментарии:
1. Вы имеете в виду получить ip-адрес (я полагаю, ipv4) локальной машины, на которой выполняется код?
2. Что делать , если существует более одного IP — адреса ? Или ни одного ?
3. на данный момент я не хочу придавать этому слишком большого значения, потому что у машины наверняка будет ip-адрес .. однако я предлагаю всегда брать первый, например, тот, что на eth0
Ответ №1:
Вы можете использовать gethostname, за которым следует gethostbyname, чтобы получить внутренний IP-адрес вашего локального интерфейса.
Вы можете попробовать этот код:
struct IPv4
{
unsigned char b1, b2, b3, b4;
};
bool getMyIP(IPv4 amp; myIP)
{
char szBuffer[1024];
#ifdef WIN32
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 0);
if(::WSAStartup(wVersionRequested, amp;wsaData) != 0)
return false;
#endif
if(gethostname(szBuffer, sizeof(szBuffer)) == SOCKET_ERROR)
{
#ifdef WIN32
WSACleanup();
#endif
return false;
}
struct hostent *host = gethostbyname(szBuffer);
if(host == NULL)
{
#ifdef WIN32
WSACleanup();
#endif
return false;
}
//Obtain the computer's IP
myIP.b1 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b1;
myIP.b2 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b2;
myIP.b3 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b3;
myIP.b4 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b4;
#ifdef WIN32
WSACleanup();
#endif
return true;
}
Используйте функции htonl, htons, ntohl, ntohs для преобразования между сетевым и локальным порядками байтов.
Комментарии:
1. Я планирую получить свой ip-адрес (ipv4), я планирую преобразовать это в байты, а затем поместить эти байты в сообщение, которое будет отправлено в многоадресной рассылке
2. Winsock также не является кроссплатформенным.
3. @Paul: Это сокеты BSD. Все содержимое winsock окружено
#if
.4. @Ben: теперь комментарии и голосование удалены, поскольку ответ теперь улучшен.
Ответ №2:
В C нет стандартного способа сделать это, потому что C также работает в системах, у которых нет сети.
Каждая операционная система имеет свой способ запроса адресов локального интерфейса. Самая «переносимая» вещь, которую вы можете надеяться найти, — это библиотека, которая предоставляет единый согласованный интерфейс с базовыми реализациями, соответствующими всем основным операционным системам.
Ответ №3:
Как сказал Бен, вы могли бы использовать нестандартную библиотеку, которая имеет реализации для многих операционных систем. boost ни в коем случае не является серебряной пулей, но библиотека boost asio — это действительно полезная, хорошо продуманная, переносимая сетевая библиотека с реализациями для многих операционных систем. В частности, asio предоставляет метод ip::host_name .
Ответ №4:
Для преобразования IP-адреса в строку можно использовать два метода: inet_ntoa (только для IPv4) или getnameinfo с флагом NI_NUMERICHOST (IPv4 и IPv6).