Construí una biblioteca para programación puramente multiplataforma. Mis juegos creados con él funcionan bien en Android, PC, Linux, Mac, etc.
La biblioteca ENET proporciona las capacidades de red, por lo tanto, toda la comunicación entre mis aplicaciones no es compatible con TCP o UDP, sino solo en el protocolo personalizado, incluso si está basado en UDP en última instancia.
No creo que sea posible hacer lo que quiero con ENET, ¡por eso pido ayuda aquí!
Digamos que tengo el mismo juego ejecutándose en mi teléfono Android, mi computadora portátil y mi PC. Todos están en la misma red wifi y, por lo tanto, en una LAN, ya sea punto de acceso Wifi (?) O el enrutador doméstico.
Necesito que cada uno de esos 3 pares descubra los otros dos en la red. Esto está destinado solo a encontrar la IP de las aplicaciones vivas en la red LAN, para poder albergar juegos multijugador entre ellas.
Solo puedo pensar en una forma efectiva de hacer esto, la transmisión UDP, esperar respuestas, pero si esa es la solución, necesito algo pequeño, ya que es el único propósito de la implementación.
Otra forma podría ser intentar conectarse a todas las IP en el subrango de direcciones LAN, pero no creo que el sistema operativo esté conmigo en este caso: p
fuente
Respuestas:
Como mucha gente ha estado diciendo, la solución sería usar la transmisión UDP , pero hay muchos detalles de implementación involucrados. Recientemente me encontré con el mismo problema, y después de encontrar una solución, publiqué un blog y un proyecto de muestra en forma de servidor / cliente de chat LAN. Voy a resumirlos aquí, pero debe consultarlos para obtener más detalles y un código real.
Así es como funciona, basado en una descripción de Lee Salzman, creador de ENet:
La buena noticia es que ENet proporciona funciones de contenedor para usar sockets , por lo que puede hacer todo en ENet. La mala noticia es que el envoltorio es extremadamente delgado; necesitarás saber sobre programación de socket , como lo que
select()
hace. Es por eso que lo aliento a que lea la publicación del blog y el proyecto de muestra para que pueda copiar / pegar el código y ahorrar mucho tiempo.Aquí hay algunas notas y dificultades si elige hacer su propia implementación:
enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)
(oSOCK_DGRAM
para la programación de sockets antiguos)enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)
(oSO_REUSEADDR
) para que varios servidores puedan ejecutarse en la misma IPenet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)
(oSO_BROADCAST
), de lo contrario no puede enviar a la dirección de transmisión. Esto es un característica de seguridad , para dificultar la inundación accidental de la red.Lamentablemente, esta no es exactamente una solución "ligera"; el proyecto de muestra registra unos pocos cientos de LOC en total. Sería bueno si esto se empaquetara en una biblioteca de utilidades para ENet, pero descubrí que para los servidores de juegos, a menudo desea enviar más información específica del juego con la respuesta del servidor para que esto sea útil, como:
fuente
Cuando no desee abandonar su biblioteca, puede usar la fuerza bruta e intentar conectarse a cada una de las direcciones posibles. La mayoría de las líneas domésticas son redes de clase C (/ 24) donde los primeros 24 bits de la dirección IP son iguales y los últimos 8 bits difieren. Por lo tanto, solo tiene 255 direcciones IP posibles.
Pero aún así, hacer una transmisión UDP sería la alternativa más limpia. Simplemente envíe un paquete UDP a 255.255.255.255 y todos los clientes detrás del mismo enrutador lo recibirán. Luego pueden enviar una respuesta a la IP de origen y al puerto de origen del paquete para informar al remitente que están presentes.
fuente
Puede echar un vistazo a DNS-SD / ZeroConf / Avahi / Bonjour / mDNS . Es lo que Apple usa para compartir impresoras, carpetas de iTunes, etc., pero se ha adoptado en otros lugares. Avahi es la versión de código abierto que usa Linux (no estoy seguro si es solo Linux), no estoy seguro de qué tan portátil es todo (aunque hay implementaciones para la mayoría de las plataformas).
Habiendo dicho todo eso, probablemente sea más fácil simplemente hacer la transmisión UDP.
fuente