Получить мой IP-адрес и преобразовать его в байты с помощью C

#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).