Sockets - Chat Simples

Boa tarde a todos, estou estudando um pouco de sockets, mais especificamente para montar um servidor de bate papo bem simples. O codigo abaixo retirei da apostila da Caellum. Creio que eu tenha entendido o conceito de Sockets, porém estou com uma dúvida pontual entre as linhas 15 até a linha 34, da classe Cliente.

Vou tentar explicar o meu raciocínio. Na classe servidor dentro do método executa, é criado um loop infinito “while (true)” (linha 21) que fica aguardando solicitações dos clientes. Dentro do cliente não é criado um loop infinito para aguardar as respostas do servidor, é aqui que esta minha dúvida: O cliente cria uma thread para processar a resposta do servidor, mas ela não é finalizada quando não existem mais respostas? Gostaria de saber como o método funciona sem o loop infinito no cliente.

Espero ter sido bem claro!

Obrigado,

Leandro

1 public class Cliente {
2 	public static void main(String[] args) throws UnknownHostException, IOException {
3 		// dispara cliente
4 		new Cliente("127.0.0.1", 12345).executa();
5 	}
6
7 	private String host;
8 	private int porta;
9
10 	public Cliente (String host, int porta) {
11 		this.host = host;
12 		this.porta = porta;
13 	}
14
15 	public void executa() throws UnknownHostException, IOException {
16 		Socket cliente = new Socket(this.host, this.porta);
17 		System.out.println("O cliente se conectou ao servidor!");
18
19 		// thread para receber mensagens do servidor
20 		Recebedor r = new Recebedor(cliente.getInputStream());
21 		new Thread(r).start();
22
23 		// le msgs do teclado e manda pro servidor
24 		Scanner teclado = new Scanner(System.in);
25 		PrintStream saida = new PrintStream(cliente.getOutputStream());
26 		while (teclado.hasNextLine()) {
27 			saida.println(teclado.nextLine());
28 		}
29
30 		saida.close();
31 		teclado.close();
32 		cliente.close();
33 	}
34 }


1 public class Recebedor implements Runnable {
2
3 	private InputStream servidor;
4
5 	public Recebedor(InputStream servidor) {
6 		this.servidor = servidor;
7 	}
8
9 	public void run() {
10 		// recebe msgs do servidor e imprime na tela
11 		Scanner s = new Scanner(this.servidor);
12 		while (s.hasNextLine()) {
13 			System.out.println(s.nextLine());
14 		}
15 	}
16 }


1 public class Servidor {
2
3 	public static void main(String[] args) throws IOException {
4 		// inicia o servidor
5 		new Servidor(12345).executa();
6 	}
7
8 	private int porta;
10 	private List<PrintStream> clientes;
11
12 	public Servidor (int porta) {
13 		this.porta = porta;
14 		this.clientes = new ArrayList<PrintStream>();
15 	}
16
17 	public void executa () throws IOException {
18 		ServerSocket servidor = new ServerSocket(this.porta);
19 		System.out.println("Porta 12345 aberta!");
20
21 		while (true) {
22 			// aceita um cliente
23 			Socket cliente = servidor.accept();
24 			System.out.println("Nova conexão com o cliente " +
25 				cliente.getInetAddress().getHostAddress()
26 			);
27
28 			// adiciona saida do cliente à lista
29 			PrintStream ps = new PrintStream(cliente.getOutputStream());
30 			this.clientes.add(ps);
31
32 			// cria tratador de cliente numa nova thread
33 			TrataCliente tc = new TrataCliente(cliente.getInputStream(), this);
34 			new Thread(tc).start();
35 		}
36
37 	}
38
39 	public void distribuiMensagem(String msg) {
40 		// envia msg para todo mundo
41 		for (PrintStream cliente : this.clientes) {
42 			cliente.println(msg);
43 		}
44 	}
45 }

1 public class TrataCliente implements Runnable {
2
3 	private InputStream cliente;
4 	private Servidor servidor;
5
6 	public TrataCliente(InputStream cliente, Servidor servidor) {
7 		this.cliente = cliente;
8 		this.servidor = servidor;
9 	}
10
11 	public void run() {
12 		// quando chegar uma msg, distribui pra todos
13 		Scanner s = new Scanner(this.cliente);
14 		while (s.hasNextLine()) {
15 			servidor.distribuiMensagem(s.nextLine());
16 		}
17 		s.close();
18 	}
19 }

Na linha 12 da classe Recebedor, o while, fica lendo as mensagens do servidor enquanto tiver linhas pra ler…

Ok, este ponto eu entendi, mas o servidor manda uma linha e para, até outro cliente enviar mensagem. Eu queria entender como o thread não morre nesse espaço de tempo.

Leandro

Estou percebendo que minha dúvida tem mais haver com o hasNextLine()

Por que existe um while, dentro de cada thread responsavel para tratamento de mensagens do cliente…

while (s.hasNextLine()) {  
      servidor.distribuiMensagem(s.nextLine());  
}

nessa parte do código, enquanto não for perdida a conexao com o cliente ou o cliente enviar uma mensagem de finalização, o while continuará rodando…

o comando hasNextLine(), verifica se existe uma linha pra ler, o comando nextLine() vai ficar esperando até que receba uma linha do cliente… ai a thread fica parada nesse ponto…