Dúvidas Básicas de Socket

Fala galera, Tudo bom?

Estou estudando um tutorial de chat e ja consegui enviar e receber mensagens!
Porém, nao entendi uma parte deste código abaixo ,

Exatamente essa parte aqui :

Scanner in = new Scanner(socket.getInputStream()); PrintWriter out = new PrintWriter(socket.getOutputStream());

Não entendi muito bem o que esta acontecendo ^
Podem me ajudar?

Segue o método run do código;

[code]@Override
public void run() {
try{
Scanner chat = new Scanner(System.in);
Scanner in = new Scanner(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream());

       while(true)
       {
           String input = chat.nextLine();
           out.println(input);
           out.flush();
           if(in.hasNext())
           {
               System.out.println("" + in.nextLine());
           }
       }
       
   } catch(Exception e)
   {
        System.out.println(e.getMessage());
        e.printStackTrace();
   }
    
}[/code]

Estudei o código aqui :

Boa tarde.

O método socket.getInputStream() é responsável por retornar o fluxo de entrada da Socket, para a leitura do que é enviado pela outra ponta.

No caso, você optou por utilizar o Scanner, pois ele oferece métodos mais “convenientes” para a leitura de sua Stream, como ler próximo número, próxima linha, etc. Ao invés de trabalhar diretamente com os bytes que são recebidos.

O mesmo para o PrintWriter para envio diretamente de linhas (println) à sua socket.

Espero ter ajudado.

Valeu!
Bruno

// Criada uma instância de Scanner que lê dados a partir de uma instância // de InputStream. Usa-se o método getInputStream para obter o objeto // InputStream associado ao Socket. Scanner in = new Scanner(socket.getInputStream()); // Criada uma instância de PrintWriter que escreve dados em uma instância // de OutputStream. Usa-se o método getOutputStream para obter o objeto // OutputStream associado ao Socket. PrintWriter out = new PrintWriter(socket.getOutputStream());

InputStream e OutputStream são classes abstratas que definem os comportamentos básico necessários às operações de leitura e escrita de bytes, respectivamente. A classe Scanner e a classe PrtinWriter disponibilizam operações para serem realizadas sobre objetos InputStream e OutputStream, no caso, leitura e escrita de texto formatado.

Muito Obrigado gente, acho que saquei.

Mais uma pergunta,Tem outro Objeto que posso usar alem desses dois ? O Print e o Scanner?

O DataInputStream e o DataOutputStream, para o caso de protocolos binários.
Protocolos binários costumam a ser mais eficientes e mais fáceis de implementar.

Porém, não são legíveis a olho nú (o que muitas vezes é uma vantagem).

[quote=ViniGodoy]O DataInputStream e o DataOutputStream, para o caso de protocolos binários.
Protocolos binários costumam a ser mais eficientes e mais fáceis de implementar.

Porém, não são legíveis a olho nú (o que muitas vezes é uma vantagem).[/quote]

Boa noite Viny!!

Como assim Protocolos Binários?

Protocolos onde não é transmitido a informação na forma de texto, mas sim, diretamente em sua forma binária.

É exatamente o mesmo conceito de um arquivo binário e de um arquivo texto. Tente ler o que conteúdo de qualquer arquivo .exe e você vai ver do que estou falando.

[quote=ViniGodoy]Protocolos onde não é transmitido a informação na forma de texto, mas sim, diretamente em sua forma binária.

É exatamente o mesmo conceito de um arquivo binário e de um arquivo texto. Tente ler o que conteúdo de qualquer arquivo .exe e você vai ver do que estou falando.[/quote]

Hmm.Entendi.
No caso, então no caso o DataInputStream receberia o socket.getInputStream como parâmetro,por exemplo ?

Por exemplo, num protocolo de texto, o número 2.120.120.123, se transmitido sem os pontinhos ocuparia 10 bytes, isso se você codificar o texto em UTF-8.
Em um protocolo binário, você codificaria essa informação na forma de um int, e ela ocuparia apenas 4 bytes.

[quote=Andre Lopes]Hmm.Entendi.
No caso, então no caso o DataInputStream receberia o socket.getInputStream como parâmetro,por exemplo ? [/quote]

Sim. Ele seria usado no lugar do PrintWriter e do Scanner (não foi o que você perguntou)?

Dê uma olhada nesse tópico, que fala mais sobre o assunto:

[quote=ViniGodoy]Por exemplo, num protocolo de texto, o número 2.120.120.123, se transmitido sem os pontinhos ocuparia 10 bytes, isso se você codificar o texto em UTF-8.
Em um protocolo binário, você codificaria essa informação na forma de um int, e ela ocuparia apenas 4 bytes.[/quote]

Ahh Entendi.
Agora sim rsrs :smiley: , Valeu Viny!!!

Valeu gente!!

O PrintWriter e o Scanner transmitem texto. Isso é, eles fazem o socket esperar constantemente por um separador, no caso, a quebra de linha, \n.
O DataInputStream e o DataOutputStream não dependem de separador. Por isso a preocupação de transmitir tamanhos de dados, descrita no tópico que linkei.

Protocolos binários são muitíssimo mais eficientes do que protocolos texto.

São exemplos de protocolos binários famosos na internet o DHCP, o SSH e os protocolos de aplicações em geral, como Messenger, Skype, Wow…
São exemplos de protocolos texto famosos o FTP, HTTP, SMTP, POP3 e o SIP.

Só mais uma pergunta gente,
Se é OutputStream, como que o InputStream vai saber, que o que esta chegando é uma String, um arquivo, uma música … etc… ?

Como que é feito isso ?

Não vai. Você irá colocar algum campo em sua mensagem que diga isso.

Entendi.

Consegui fazer uma view que mostra a mensagens que os usuários digitam, etc…

Mas, agora tenho uma outra dúvida!
O servidor tem um arrayList dos usuários conectados!
Como eu faço pra enviar esse arrayList pro usuario, pra ele saber quem esta conectado?

[quote=Andre Lopes]Entendi.

Consegui fazer uma view que mostra a mensagens que os usuários digitam, etc…

Mas, agora tenho uma outra dúvida!
O servidor tem um arrayList dos usuários conectados!
Como eu faço pra enviar esse arrayList pro usuario, pra ele saber quem esta conectado?
[/quote]

Olá.

Tente dar uma estudada em Serialização de objetos

Você transforma seu objeto em bytes (serializa) na ponta de origem, transfere via stream/socket e na outra ponta você deserializa o que veio - recebendo uma cópia exata do seu objeto.

Você cria uma mensagem para isso.

Se seu protocolo for texto, poderia ser uma mensagem com todos os nomes separados por vírgula.

No caso de Serialização, eu preciso criar um novo socket somente pra receber o objeto arrayList ?
Porque, o único socket que tenho é pra receber as mensagens. Como que vou diferenciar uma mensagem de um array?
If( getInput == String) ???

Por exemplo :

Você não vai enviar o array inteiro. Vai enviar uma mensagem, descrevendo o conteúdo do array. O outro lado recebe essa mensagem e refaz o array.

Mas como eu faço isso?
Porque eu só sei usar o PrintWriter pra enviar uma String e receber ela!

Como que vou saber que é uma String ou um array?