Como são feitos os chats?

Indrodução(pulem essa parte se quiserem :wink:)
Salve! No começo deste ano, tive que decidir sobre qual seria meu TCC. No técnico que eu faço o pessoal(professores e adm da escola…) é meio limitado e poda a criatividade dos alunos. Tudo que sai de TCC são sistemas comerciais, do tipo locadora.E por incrível que pareça, conseguem fazer malfeito(apesar de serem feitos em Delphi e VB que facilita e muito a criação de sistemas como esses). Decidi fazer diferente, escolhi java como linguagem de programação( e Oracle como BD), talvez por sua portabilidade mas principalmente pelo aprendizado que a linguagem pode me proporcionar. O tema não ficou atráz: trata-se de um sistema integrado com parte web, client-server e um sistema interno que, no fim das contas, serve pra controlar dispositivos eletrônicos com uma interface gráfica amigável para o usuário e com a segurança exigida para esses sistemas. No começo, não sabia se ia chegar ou como terminar, só sabia como começar.

Dúvida:
Acreditei que funcionaria como um chat… então fiz umas rotinas via socket (começando com um chat em rede), fui aprimorando a GUI, coloquei comunicação serial … numa rede interna funcionou perfeitamente!!! O problema é que na internet não funciona: não consigo localizar o ip do cliente pois o ip que eu pego é o IP interno. Via socket, vc até consegue pegar o IP externo, mas isso não adianta para se conectar a um host específico dentro da rede.
Aqui no GUJ, me sugeriram para configurar o router para redirecionar determinada porta para determinado host, e acredito que isso funciona. Mas voltei ao meu primeiro raciocínio: deve funcionar como um chat. É claro que é possivel fazer um msn ou coisa do tipo em JAVA, então como é feito? Para quem é direcionado o IP nos sockets, e se sockets não sao usados, como faço para enviar as mensagens ( ou strings, classes, stream de vídeo :?) de outra forma? Quem já tiver feito algum chat ou programa que trabalhe de forma semelhante por favor me dê uma luz.

Qualquer sugestão eu agradeço :slight_smile:

O msn messenger, IrC, ICQ, etc. tem um servidor no meio. Nesse servidor, o NAT está configurado para aceitar conexões.
Os dois clientes (com ips internos) conectam no servidor, que passa a conhecer seus endereços. O servidor então serve de ponte entre os dois.

Se você fez UDP, pode usar também a técnica ninja-gaiden de hole punching para tapear os nats internos, também usando um servidor. A vantagem é que no final você acaba com uma conexão peer-to-peer.

obrigado novamente vinícius :wink: então, na prática, ao invez do meu servidor ser um segundo nível de complexidade ele facilita as coisas. Então eu só preciso configurar o meu router ao invéz de configurar o de cada cliente como eu suspeitava? Corrija-me se eu estiver errado

Adequando ao meu sistema… eu fiz ele da seguinte maneira: quando o usuário usa a applet para controlar a sua casa, é preciso que a applet saiba o IP da casa. Então, existe um robo que monitora a conexão do cliente e envia por socket o ip dele ao meu banco.Não é vantagem nenhuma que o cliente use um ip fixo ( isso seria um crime contra a internet!) e exitem portanto 3 computadores nessa brincadeira: o servidor ( da empresa), o controlador(que tem a placa com o equipamento para controlar suas lampadas, cameras,portoes), e o que faz o acesso á applet. Tem como eu fazer que, quando o cliente acessar a applet de um computador qualquer, seja enviado por socket uma string pro pc controlador? Sua idéia é boa, mas tem como eu fazer isso mexendo apenas no meu router(servidor) e não de cada um dos clientes?

É isso mesmo. Cada cliente só precisa saber o endereço do servidor. E só.

Até porque, os NATs não deixam que uma mensagem se origine do mundo exterior e vá até o seu interior.

É só depois que uma mensagem sai que ele atribui ao cliente interno uma porta, associada a um endereço válido de internet. Sem que o cliente tenha iniciado a conexão esse mapeamento nem sequer existe.

  1. O “servidor da empresa” é o da empresa que monitora ou que está sendo monitorada?
  2. O controlador está na casa/empresa do cliente final, certo?
  3. O applet pode ser acessado de qualquer micro? Ele é um applet que sai do controlador ou do seu servidor?
  4. Os controladores também estão ligados ao seu servidor?

eu dei uma olhada em NAT(fonte wikipedia) e me deixou ainda mais confuso, ainda não entendo como posso enviar para determinado cliente configurando apenas o meu equipamento.(Veja, qndo chegar lá não pararia no router dele? como o router dele sabe que é para determinado host?)

1.então, o servidor da empresa é o da nossa empresa que fornece o serviço(que to montando =P)
2. Sim
3.Ele sai do servidor. Até porque colocar o applet no próprio cliente dificulta a manutenção e faz com que ele tenha que se preocupar com os procedimentos de segurança, e isso não é viavel.
4.O único momento que eles se ligam ao servidor(via socket TCP) é quando existe alguma alteração no IP e ele precisa notificar ao servidor o novo IP, caso contrário nunca encontraríamos o host.

Acho que vc tá pegando a coisa, mas vou fazer um mini-“algoritmo” pra mostrar como funciona:
No controlador:

  1. O IP é monitorado por um robo
  2. Havendo mudança de IP, é enviado para o IP X na porta Y( correspondente ao servidor, que é fixo ou vai ter DNS)a notificação do novo IP, além de outras informações como versão, usuario,senha e se precisar portas e etc.

No Servidor:

  1. O servidor aguarda conexões no IP x na porta Y
  2. Havendo conexões, ele separa os dados e guarda no banco

No Computador de Acesso(pode ser qualquer pc):

  1. O usuário se loga no sistema(usei applet/servlet pra fazer isso)
  2. Suas informações são usadas para acessar uma applet ( assinada) com a Interface
  3. O IP armazenado no banco é carregado para a applet(assim como outras informações)
  4. É enviado ao Controlador a Ordem

No controlador:

  1. É recebida e interpretada a ordem
  2. Ela é enviada via serial para o Hardware

É ± assim, qq duvida me fla que eu tento me expressar melhor, mto obrigado!!

O NAT funciona assim.

Vocë tem uma série de endereços de internet inválidos numa rede (a rede do seu cliente):
I1, I2, I3, I4.

O NAT está ligado a essa rede, mas ele tem um endereço válido, E.

Seu servidor tem um endereço S.

Se seu servidor tentar acessar o I1, não conseguirá, pois I1 não é um endereço de internet válido.

Porém se I1 tentar acessar o seu servidor, o seguinte acontece:

  1. I1 comunica-se com o NAT;
  2. O NAT cria associa I1 a uma porta, PI1. Essa informação fica gravada numa hashtable interna do NAT. Então, ele substitui o endereço de origem I1 por um endereço próprio. E: PI1.
  3. Seu servidor recebe a mensagem. Então, ele responde para quem enviou para ele, ou seja, o NAT (E: P1)
  4. O NAT recebe a resposta. Como a mensagem foi enviada para a porta PI1, basta que o NAT consulte sua hashtable pra descobrir que as solicitações que partem dessa porta se referem ao endereço I1. Então, esse pacote é encaminhado para o computador da rede interna.

Note que se um computador da rede interna não iniciar uma comunicação, não há como alguém de fora conversar com ele.

foi assim que eu entendi. Justamente por isso minha dúvida =P. Dessa forma que vc descreveu, o cliente tem que ter necessáriamente o servidor NAT não é? pq é no router dele ( ou pc dele nao sei) que está essa tabela de porta/ip. Pelo que vi do nat, vc precisa deixar rodando dois servers pra que isso funcione. Posso estar enganado, mas é esse servidor nat que faz essa verificação na tabela não é? ou ele apenas serve pra responder uma solicitação de qq cliente?

veja o esquema:

…S(ligado a Xs)
I1
I2---------X1-------------Xs-------------------X2----------Ir4
I3

I1: IP inválido 1, usado somente internamente
X: roteadores. Dois X seguidos indica internet
S: Servidor
Ir4: computador que carrega a applet.

Qndo o controlador(I1) envia o pacote ao servidor, ele passa primeiro pelo roteador1(X1) e este troca o IP inválido por um ip válido na rede. Então,
o pacote é direcionado para o Xs e este repassa para S. S recebe o pacote e guarda as informações no banco.
Qndo o Ir4 acessa o servidor e carrega a applet, ele pega o IP que foi enviado ( o IP do X1 ou do I1). Ele envia para o IP do X1, mas antes passa pelo Xs. O Xs tem um servidor NAT.

Não vejo como, a partir daí fazer com que o pacote chegue em I1 fazendo configurações ou instalações apenas em Xs ou em S. :?

Mais uma vez obrigado ^^

Obrigado pela ajuda ^^

Nem todo roteador faz NAT. O NAT só é necessário quando vc traduz o endereço de uma rede que não é internet para internet. No seu exemplo, não haveria porque Xs trocar o endereço de X1.

Na internet, todos os endereços são válidos, não há traduções de endereços e tudo é facilmente acessável. Podem haver n roteadores entre os NATs das redes dos clientes e o seu servidor, e isso não será um problema.

O seu servidor, para que essa topologia funcione, tem que ter um endereço web válido. Ou seja, ele não estará atrás de um NAT. Ou, se estiver, estará atrás de um NAT configurado para não ignorar solicitações, e encaminhar o que chegar para o seu servidor automaticamente. O importante é: seu servidor tem que poder receber conexões externas, sem te-las iniciado.

Não adianta. Agora, ambos os endereços internos e não válidos (Is) terão que ter iniciado a conexão com seu servidor. E aí, basta manter essa conexão ativa para que tudo funcione.

T
|
|
S -------- N2 -------- I2
|
|
-----------N1 -------- I1

Suponha que I1 seja o controlador, que está na rede da empresa do seu cliente. Ele deve, primeiramente, conectar-se ao servidor S. Para isso, ele vai sair do nat (N1). A partir de agora, S poderá mandar mensagens para I1 e vice-versa, já que o NAT deixou essa porta “aberta”.

O mesmo ocorre com I2. Ele também não tem um endereço válido. Está atrás de um NAT. Ele poderia ser o cliente, querendo ver o que está acontecendo na empresa através do applet. Ou mesmo outro controlador. Tanto faz. O importante é, ele está também em uma rede interna e, portanto, também vai ter que conectar com o servidor para abrir a porta do seu NAT (n2).

Agora, uma vez que os dois estão conectados. O usuário em T pode alterar qualquer coisa de I1 ou I2. Basta que os comandos sejam enviados para o servidor. Como já existe uma conexão com I1 e I2 (pois esses estão permanentemente conectados), o servidor pode reencaminhar os comandos de configuração.

Essa arquitetura tem uma desvantagem. Vocë tem que manter as conexões entre I->S permanentemente ativas. Isso também significa que seu servidor saberá a respeito de todos os controladores existentes, e deve alerta-lo quando um controlador “sair do mapa”. No caso de uma empresa de segurança, isso me parece até desejável.

Para tanto, vc tem que programar o controlador para buscar essa conexão com o servidor sempre que ele for reiniciado. Isso pode fazer parte do firmware do seu controlador.

Dois servers? Não, o NAT é um serviço que roda em um único roteador. Ele é independente, não precisa de outro server para funcionar.

Obrigado mais uma vez pela aula ^^. Sei que já estou parecendo ignorante, mas esse método força o cliente a ter um nat e como disse nem todos tem nat. Estou tentando fazer sem nenhum nat no cliente, ao que parece por esse método não tem como. Mas, uma coisa está me intrigando: como os jogos online por exemplo ou ainda o msn messenger consegue te achar na rede mesmo sem ter nat? acredito que deva usar um método parecido.

Desculpe se eu não estou ajudando; vou me justificar. Acontece que tem outro grupo fazendo o mesmo trabalho que eu. Só que no dele, não tem um servidor na empresa: ele força cada cliente ser um servidor ( de IP fixo e tudo mais!). Eu acho isso o cúmulo, como ele obriga o cliente dele ser um servidor; instalar um monte de tranqueiras e ainda fuder de vez com as estratégias geniais ( como essa do nat que vc flo) pra economizar IPs válidos? Sem falar que joga toda responsabilidade da segurança pro cliente e dificulta a manutenção :?Ainda estou intrigado: como o tio bill consegue achar o IP dentro da rede sem configurar nada no meu router?

Cara, valew pela paciência XD vo por uma dedicatória no “agradecimentos” :wink:

Cara, o tio bill não conhece o seu IP. É o seu MSN que conhece o IP dos servidores da Microsoft. Os servidores da Microsoft não estão atrás de um NAT. Então, não é ele que te acha, é vc que vai atrás dele.

É o que estou te explicando desde o início. Se o seu computador (que está na rede interna) iniciar a conversação com o servidor, está tudo bem. O servidor será capaz de responder para o seu computador. Estará criado um “tunel” entre eles, que só será fechado caso os dois fiquem um bocado de tempo em silêncio.

O que estou imaginando é ± isso que vc falou, centralizo todas as configurações no meu servidor que serve como ponte, ou coisa do tipo, mas não mexo no router cliente

Haha obrigado, qndo mandei a msg vc já havia respondido. Bom, desculpe qq coisa !! Então… não é nat, certo? Tem ideia de como eles fazem isso?

Outra coisa, é muitíssissímo pouco provável que os clientes não tenham um NAT. Como você mesmo falou, eles não terão IPs fixos associados. Portanto, estarão pelo menos atrás do NAT do provedor de internet ou da rede empresarial.

Ainda assim, se eles não tiverem um NAT, nada impede que eles se conectem diretamente ao seu servidor. O seu servidor nem sequer sabe da existência de um NAT do lado do seu cliente.

Isso, é isso mesmo! Tudo passa pelo seu servidor.

Como os clientes estão ligados ao seu servidor, vc pode trocar informações livremente entre eles. O importante é que tanto o applet, quanto o controlador, quanto o cara que vai ajustar as configurações tenham se conectado no servidor.

Você não vai fugir de configurar um servidor na internet. Mas ok, o servidor é seu. Não o do seu cliente.

O seu cliente não precisa fazer absolutamente nada. Só digitar o endereço (http://www.shamanpyro.com.br) no campo conexão e ser feliz.

haha ok. Então eu entendi a idéia, mas ainda não caiu a ficha de como eu faço isso no java…
Vamos lá:
(pode pular o código, só pra exemplificar)

  1. Pega IP e manda por socket
	InetAddress meuIP = InetAddress.getLocalHost();
		 IP =meuIP.getHostAddress();  //4 //trocar aqui pra pegar IP remoto ou nem mandar, o Socket Server consegue pegar
		//OBS: getRemoteAddr()  pega o IP remoto!!
	 }catch(Exception e)
	 {System.out.println("nao deu pra pegar o ip");}
	 try{
		  SocketCliente = new Socket(IPdoServidor, 8000); //5
	  }catch(IOException excecao)
	  {
System.out.println("Erro ao se conectar ao servidor.Verifique se este esta disponivel.");
	  }// tratamento de erros

	 try{

Pacote = IP + ";" + Usuario + " " + Senha ;

		   PrintStream StreamDeSaidaDeDados = new PrintStream(SocketCliente.getOutputStream()); //6
           		   StreamDeSaidaDeDados.println(Pacote);// 7
		   StreamDeSaidaDeDados.println(Pacote);// 8
  1. Socket Server ( no servidor) Recebe e grava no BD:
              SocketServidor = new ServerSocket(8000); // instancia serversocket e coloca a porta 8000
             Socket = SocketServidor.accept(); // 1
             Entrada = new BufferedReader(new InputStreamReader(Socket.getInputStream())); //2
....

CadastraIP.Cadastra(Usuario,IP,Senha);
  1. Applet se Envia msg via socket Pro servidor com a ordem.

  2. Como o servidor repassa daquele que ve a applet pro controlador? Como eu dou uma response em outra conexão?

Aí que está a importância do seu protocolo…

Você terá que criar mensagens para cada uma dessas coisas.

Uma mensagem para pedir para o servidor a lista dos controladores que ele conhece.
Uma mensagem para um controlador dizer a um servidor que é um controlador.
Uma mensagem que para dizer para o servidor que o controlador X deve executar um determinado comando.

Uma mensagem para o controlador dizer para o servidor que ainda está vivo.
Uma mensagem para o servidor dizer ao controlador que está vivo.

Etc… etc… etc…

SIm, muito Obrigado!!! Acredito que assim funcione. Então, eu sempre que eu receber uma mensagem eu do um getRemoteAdress