samuelVoador
(usa Debian)
Enviado em 21/07/2017 - 02:24h
Estou com uma dúvida bem estúpida, como que comunico dois computadores que estão em redes diferentes utilizando o protocolo UDP?
Vou tentar explicar melhor:
Tenho um computador "1" que está numa rede local, e nessa rede está com o
ip local 192.168.1.3
Tenho outro computador "2" que está em outra rede local, também com o
ip local 192.168.1.3(coloquei o mesmo só para ressaltar que estão em duas redes diferentes).
Então o computador 1 está conectado a internet e tem o
ip global 159.28.10.66
Então o computador 2 também está conectado a internet e tem o
ip global 176.13.40.58
Quero comunicar esses dois computadores utilizando o protocolo UDP, como que faria? Estou querendo uma conexão peer-to-peer, não consigo imaginar como funciona, li que jogos MOBA utiliza esse tipo de conexão, que é por UDP, mas ainda não entendi, como que é feita essa comunicação entre os dois computadores. Você loga na sua conta, ai o servidor do jogo irá ver que você está online e tem você e mais um conectado, por exemplo, ai ele fala, vou passar informação de um para o outro e assim os dois podem se conectar um com outro. Se for assim, o que é feito, ele passa o ip global de um para outro? e se também for assim, como do ip global vai saber qual é o ip local? Acho isso tudo muito confuso.
Antes de tudo, para entende melhor a questão, lembrem-se como era a internet no seu inicio, cada nó da rede havia um único ip válido, porém com a quantidade de nós que foram acrescentados ficou inviável, mesmo com o IPV4 não há números suficientes(ips) para satisfazer todos nós da grande rede, então assim houve a necessidade de criar algo para contornar isso, e surgiu o NAT e as redes locais, a internet não era mais apenas uma grande rede, mas um conjunto de várias outras redes, e o que esse NAT faz? Com ele foi possível traduzir um ip local(ex seu: 192.168.0.6) em um ip global válido na internet, existem vários tipos de NAT, mas o mais comum é o que nos permite utilizar um único ip global(o qual provavelmente é disponibilizado para você por sua contratante) para vários computadores em uma rede local, e o NAT que cuida disso para você, e como ele faz isso? um exemplo, temos um computador em uma rede local com ip local 192.168.0.4 que deseja acessar o
https://www.vivaolinux.com.br, abaixo passo-a-passo como acontece:
1 - O usuário do host da rede interna 192.168.0.4 digita no navegador o site do "vivaolinux"
2 - O pacote contendo as informações é encaminhado ao NAT
3 - O NAT retira as informações do IP interno e associa a requisição a uma porta unica, ex: 65660
4 - O NAT envia o pedido ao site
5 - O Site responde
6 - O NAT confere a porta e manda os pacotes para o host que solicitou
referência:
http://www.purainfo.com.br/artigos/o-que-e-como-funciona-o-nat/
Mas ai você lembrou do IPV6, e com o IPV6 não será mais necessário o uso de NAT? Possivelmente ainda usaremos, acabamos gostando da segurança adicional e privacidade que o NAT e as redes locais nos trouxeram. E o NAT também é útil para interoperabilidade entre IPV4 e o IPV6, pelo menos a curto prazo acredito que o NAT não irá desaparecer.
Então é só conectar ambos computadores no caso da questão? não é bem assim, pois o NAT bloqueia qualquer tráfico recebido que não seja configurado para ser recebido, mas pense, quando você joga algum jogo ou usa uma aplicação(claro, estou me referindo especificamente ao ponto da questão P2P-UDP), você não tem que permitir ou liberar porta alguma, como isso acontece?
Para uma comunicação UDP, peer-to-peer, é necessário 4 informações(IP local, porta local, IP remoto, porta remota), ou seja traduzindo para o caso da questão(IP local do computador 1, porta do computador 1, IP local do computador 2, porta do computador 2), então como conectaríamos os dois computadores que estão em redes diferentes(ou seja, possuem NATs diferentes), pois assim seria(IP local e global do computador 1, porta local e global do computador 1, IP local e global do computador 2, porta e global do computador 2)?
Existe uma forma, se chama perfuração UDP(UDP Hole Punching), e precisaremos de um servidor para isso, este servidor irá recolher as informações do computador 1 e do computador 2 e compartilhar de um para o outro para que eles possam se conectar diretamente. Irei explicar abaixo uma das maneiras de utilizar "UDP Hole Punching" no caso da questão com dois computadores em NATs diferentes:
1 - Computador 1 e computador 2 iniciaram uma sessão com o servidor com a porta local 4321 para a porta 1234 no servidor.
2 - O NAT do computador 1 atribui a porta 63600 para o ip global(público, no caso da questão, seria o 159.28.10.66). O NAT do computador 2 atribui a porta 30100 para o ip global(público, no caso da questão, seria o 176.13.40.58).
3 - O computador 1 envia os IPs e portas locais(privados) e globais(públicos) para o servidor. O computador 2 faz a mesma coisa.
4 - Agora o computador 1 pede ajuda do servidor para se conectar ao computador 2, então o servidor passa as informações para o computador 1, o IP e porta local(privado) e global(público) do computador 2. E o servidor passa as informações para o computador 2, o IP e porta local(privado) e global(público) do computador 1.
5 - O computador 1 e computador 2 podem enviar pacotes um para o outro.
referência:
http://www.brynosaurus.com/pub/net/p2pnat/
http://www.raknet.net/raknet/manual/natpunchthrough.html
E se dois usuários tiverem dentro de uma mesma rede(com um mesmo NAT)? não irei explicar aqui, mas no link acima explica, e também o caso de existir mais de uma camada, ou seja um NAT em cima de outro NAT.
Então consegui entender e responder a questão que estava com dúvida, agora gostaria de saber, preciso implementar isso em meu jogo, está portado para android, enviar os pacotes por UDP eu já implementei com uma API para isso( na verdade estou terminando de escreve-la utilizando Enet, não sei ainda se funciona, mas espero que sim kkk), gostaria é de saber, e do lado do servidor, existe alguma API que faça essa "perfuração de NAT", e se é essa a melhor forma de comunicar dois computadores por UDP-P2P(P2P pois a API que estou escrevendo é P2P, não é necessário ser cliente-servidor, pois é apenas 2 ou no máximo 3 jogadores, o que P2P segura numa boa) para jogos multiplayer em tempo real?