как написать программу, сообщающую локальный IP-адрес, например 192.168.1.102?
-
21-08-2019 - |
Вопрос
поскольку мой маршрутизатор Linksys не назначает фиксированный локальный IP-адрес компьютерам (ПК, Mac и Linux), я хотел бы написать сценарий, чтобы каждую минуту компьютеры обновлялись друг с другом, чтобы
на каждой машине будет содержать список имен всех ПК и Mac и ссылку на их сервер Apache (указывающую на http://192.168.1.102, и т. д)
Похоже, что способ узнать локальный IP-адрес — это ipconfig на ПК и ifconfig на Mac и Linux, а чтобы сделать это программно, это будет gethostbyname().
Но я пробовал на Ruby, это
irb(main):001:0> require 'socket'
=> true
irb(main):002:0> p Socket::gethostbyname("localhost")
["Core2Duo", [], 2, "\177\000\000\001"]
irb(main):005:0> p Socket::gethostbyname("core2duo")
["Core2Duo", [], 2, "\300\250\001g"]
=> nil
и ipconfig действительно показывает
IPv4 Address. . . . . . . . . . . : 192.168.1.103
так это правильный способ сделать это?Я могу взломать его, выполнив «ipconfig» в Ruby и используя регулярное выражение для получения результата, но было бы неплохо сделать это более стандартным способом.
Решение
Socket::getaddrinfo
может быть больше того, что вы ищете:
Socket::getaddrinfo('localhost', 'http')
[["AF_INET", 80, "localhost", "127.0.0.1", ...]]
Socket::getaddrinfo('core2duo', 'http')
[["AF_INET", 80, "Core2Duo", "192.168.1.103", ...]]
Или вы можете просто попробовать:
Socket::getaddrinfo('core2duo', 'http')[0][3]
"192.168.1.103"
Другие советы
Вы можете сделать это в Java, используя:
Socket s = new Socket();
s.getLocalSocketAddress();
Если вы используете Bonjour в своих системах Windows и avahi в своих системах Linux, вы можете избавиться от необходимости определять IP-адрес каждой системы.Затем вы можете просто обратиться к каждой системе, используя "hostname.local
".Больше информации здесь.
Почему бы просто не отключить DHCP для этих машин и не назначить им фиксированные IP-адреса?
Редактировать в ответ на комментарии:По крайней мере, примерно три года назад (когда я в последний раз покупал маршрутизатор) маршрутизаторы Linksys позволяли вам устанавливать нижний IP-адрес для встроенного DHCP-сервера.Затем вы переходите к настройке сети отдельных компьютеров, отключаете DHCP и назначаете физические адреса.Например, в моей домашней сети роутер 192.168.1.1, Terastation 1.2, принтер 1.3, мой Linux-бокс 1.99, а роутер настроен на выдачу 1.100 и выше.
Проблема в сценарии Ruby может заключаться в том, что в вашей сети нет разрешения DNS-имен, это часто скрыто, если вы обычно обмениваетесь данными между компьютерами с SMB/CIFS, поскольку у них есть собственный протокол обнаружения имен.
Если вы собираетесь передавать дейтаграммы с информацией об имени/IP, то вам не обязательно, чтобы ПК знал свой собственный IP-адрес.Просто отправьте датаграмму, содержащую ее имя, а затем используйте получение из() - или эквиваленты - чтобы поймать его на других компьютерах.Таким образом, получатели могут извлечь IP-адрес отправителя непосредственно через получение из() функция.
В качестве бонуса это должно работать, если на отправляющем компьютере имеется более одного сетевого адаптера.