Criei uma biblioteca para programação puramente multiplataforma. Meus jogos feitos com ele funcionam bem no Android, PC, Linux, Mac etc.
Os recursos de rede são fornecidos pela biblioteca ENET, portanto, toda a comunicação entre meus aplicativos não é compatível com TCP ou UDP, mas apenas no protocolo personalizado, ainda que seja baseada no UDP.
Eu não acho que é possível fazer o que eu quero com a ENET, é por isso que peço aqui ajuda!
Vamos dizer que eu tenho o mesmo jogo rodando no meu telefone Android, meu laptop e meu PC. Eles estão todos na mesma rede wifi e, portanto, em uma LAN, seja seu ponto de acesso Wifi (?) Ou o roteador doméstico.
Eu preciso que cada um desses três pares descubra os outros dois na rede. Isso serve apenas para encontrar o IP de aplicativos ativos na rede LAN, para poder hospedar jogos multiplayer entre eles.
Só consigo pensar em uma maneira eficaz de fazer isso, transmissão UDP, respostas de espera, mas se essa é a solução, preciso de algo pequeno, pois é o único objetivo da implementação.
Outra maneira poderia ser tentar se conectar a todos os IPs no subintervalo de endereço LAN, mas não acho que o sistema operacional estaria comigo neste caso: p
fonte
Respostas:
Como muitas pessoas dizem, a solução seria usar a transmissão UDP , mas há muitos detalhes de implementação envolvidos. Recentemente, encontrei o mesmo problema e, depois de elaborar uma solução, criei uma postagem no blog e um projeto de amostra na forma de um servidor / cliente de chat da LAN. Resumirei esses aqui, mas você deve consultá-los para obter mais detalhes e código real.
Veja como funciona, com base na descrição de Lee Salzman, criador do ENet:
A boa notícia é que o ENet fornece funções de invólucro para o uso de soquetes , para que você possa fazer tudo no ENet. A má notícia é que o invólucro é extremamente fino; você precisará saber sobre programação de soquetes , como o que
select()
faz. É por isso que incentivo você a dar uma olhada na postagem do blog e no projeto de amostra para poder copiar / colar o código e economizar muito tempo.Aqui estão algumas notas e armadilhas, se você optar por fazer sua própria implementação:
enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)
(ouSOCK_DGRAM
para a programação simples de soquetes antigos)enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)
(ouSO_REUSEADDR
) para que vários servidores possam ser executados no mesmo IPenet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)
(ouSO_BROADCAST
), caso contrário, não poderá enviar para o endereço de broadcast. Esse é apenas um recurso de segurança , para dificultar a inundação acidental da rede.Infelizmente, essa não é exatamente uma solução "leve"; o projeto de amostra gera algumas centenas de LOC. Seria bom se isso fosse empacotado em uma biblioteca de utilitários para ENet, mas eu descobri que, para servidores de jogos, muitas vezes você deseja enviar mais informações específicas do jogo com a resposta do servidor para tornar isso útil, como:
fonte
Quando não quiser sair da sua biblioteca, você pode simplesmente usar força bruta e tentar se conectar a cada um dos endereços possíveis. A maioria das redes domésticas são redes de Classe C (/ 24), onde os primeiros 24 bits do endereço IP são iguais e os últimos 8 bits diferem. Então você tem apenas 255 endereços IP possíveis.
Mas, ainda assim, fazer uma transmissão UDP seria a alternativa mais limpa. Basta enviar um pacote UDP para 255.255.255.255 e todos os clientes atrás do mesmo roteador o receberão. Eles podem enviar uma resposta ao IP de origem e à porta de origem do pacote para informar ao remetente que eles estão presentes.
fonte
Você pode dar uma olhada no DNS-SD / ZeroConf / Avahi / Bonjour / mDNS . É o material que a Apple usa para compartilhar impressoras, pastas do iTunes e assim por diante, mas foi adotado em outros lugares. Avahi é a versão de código-fonte aberto que o Linux usa (não tenho certeza se é apenas Linux), não tenho certeza de quão portátil é a coisa toda (embora existam implementações para a maioria das plataformas).
Dito tudo isso, provavelmente é mais fácil fazer a transmissão UDP.
fonte