Я построил библиотеку для чисто кроссплатформенного программирования. Мои игры, сделанные с его помощью, прекрасно работают в Android, ПК, Linux, Mac и т. Д.
Сетевые возможности обеспечиваются библиотекой ENET, поэтому вся связь между моими приложениями не совместима с TCP или UDP, а только в настраиваемом протоколе, даже в конечном счете основанном на UDP.
Я не думаю, что с ENET можно делать то, что я хочу, вот почему я прошу здесь о помощи!
Допустим, у меня на Android-телефоне, ноутбуке и компьютере запущена одна и та же игра. Все они находятся в одной сети Wi-Fi и, следовательно, в локальной сети, будь то точка доступа Wi-Fi (?) Или домашний маршрутизатор.
Мне нужно, чтобы каждый из этих трех пиров обнаружил двух других в сети. Это предназначено только для того, чтобы найти IP живых приложений в сети LAN, чтобы иметь возможность размещать многопользовательские игры между ними.
Я могу думать только об одном эффективном способе сделать это: широковещательная рассылка UDP, ожидание ответов, но если это решение, мне нужно что-то маленькое, поскольку это единственная цель реализации.
Другим способом может быть попытка подключиться ко всем IP-адресам в поддиапазоне адресов LAN, но я не думаю, что ОС будет со мной на этом: p
источник
Ответы:
Как уже говорили многие люди, решение будет заключаться в использовании широковещательной передачи UDP , но в нем много деталей реализации. Недавно я столкнулся с той же проблемой, и после разработки решения я сделал сообщение в блоге и пример проекта в виде сервера / клиента чата локальной сети. Я буду обобщать их здесь, но вы должны проверить их для более подробной информации и реального кода.
Вот как это работает, основываясь на описании Ли Зальцмана, создателя ENet:
Хорошей новостью является то, что ENet предоставляет функции-оболочки для использования сокетов , так что вы можете делать все в ENet. Плохая новость заключается в том, что обертка очень тонкая; вам нужно знать о программировании сокетов , например, что
select()
делает. Вот почему я рекомендую вам взглянуть на сообщение в блоге и пример проекта, чтобы вы могли скопировать / вставить код и сэкономить много времени.Вот некоторые замечания и подводные камни, если вы решите сделать свою собственную реализацию:
enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)
(илиSOCK_DGRAM
для простого программирования сокетов)enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)
(илиSO_REUSEADDR
), чтобы несколько серверов могли работать на одном IP- адресеenet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)
(илиSO_BROADCAST
), иначе вы не сможете отправить на широковещательный адрес. Это только функция безопасности , чтобы затруднить случайное затопление сети.К сожалению, это не совсем «легкое» решение; всего пример проекта составляет несколько сотен LOC. Было бы неплохо, если бы они были упакованы в служебную библиотеку для ENet, но я обнаружил, что для игровых серверов вы часто хотите отправить дополнительную информацию, специфичную для игры, с ответом сервера, чтобы сделать это полезным, например:
источник
Если вы не хотите покидать свою библиотеку, вы можете просто использовать грубую силу и попытаться подключиться к каждому из возможных адресов. Большинство домашних сетей представляют собой сети класса C (/ 24), в которых первые 24 бита IP-адреса совпадают, а последние 8 бит отличаются. Таким образом, у вас есть только 255 возможных IP-адресов.
Но тем не менее, выполнение UDP-трансляции было бы более чистой альтернативой. Просто отправьте пакет UDP на 255.255.255.255, и все клиенты за одним маршрутизатором получат его. Затем они могут отправить ответ на исходный IP-адрес и исходный порт пакета, чтобы сообщить отправителю, что они присутствуют.
источник
Вы можете взглянуть на DNS-SD / ZeroConf / Avahi / Bonjour / mDNS . Это то, что Apple использует для обмена принтерами, папками iTunes и т. Д., Но оно было принято в других местах. Avahi - это версия с открытым исходным кодом, которую использует Linux (не уверен, что это только Linux), не уверен, насколько она переносима (хотя существуют реализации для большинства платформ).
Сказав все это, вероятно, проще сделать UDP-трансляцию.
источник