SD 2018-Q2 - Prática
Correção Exercícios - Prática Aula 01
Segundo Quadrimestre de 2018
Professor: Emilio Francesquini
E-mail: e.francesquini@ufabc.edu.br
Exercício 1
- Utiliza TCP/IP - Orientado a conexão
- Um único cliente por servidor
- Desperdiça CPU pois fica num laço de espera ocupada
Download do .java
para o Servidor e para o Cliente:
Cliente
import java.io.*; import java.net.*; public class Aula01_Ex01_Cliente { public static void main(String[] args) throws IOException { if (args.length != 2) { System.err.println( "Forma de uso: java Aula01_Ex01_Cliente <end. servidor> <porta>"); System.exit(1); } String hostName = args[0]; int portNumber = Integer.parseInt(args[1]); try ( Socket socket = new Socket(hostName, portNumber); PrintWriter socketOut = new PrintWriter(socket.getOutputStream(), true); BufferedReader socketIn = new BufferedReader( new InputStreamReader(socket.getInputStream())); BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)) ) { while (true) { if (stdIn.ready()) { String userInput = stdIn.readLine(); socketOut.println(userInput); if ("SAIR".equals(userInput)) break; } if (socketIn.ready()) { String msg = socketIn.readLine(); System.out.println(">" + msg); if ("SAIR".equals(msg)) break; } } } catch (UnknownHostException e) { System.err.println("Endereço desconhecido " + hostName); System.exit(1); } catch (IOException e) { System.err.println("Erro conectanto em: " + hostName); System.exit(1); } } }
Servidor
import java.net.*; import java.io.*; public class Aula01_Ex01_Servidor { public static void main(String[] args) throws IOException { if (args.length != 1) { System.err.println("Forma de uso: java Aula01_Ex01_Servidor <porta>"); System.exit(1); } int portNumber = Integer.parseInt(args[0]); try ( ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0])); Socket clientSocket = serverSocket.accept(); PrintWriter clientOut = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader clientIn = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)) ) { while (true) { if (stdIn.ready()) { String userInput = stdIn.readLine(); clientOut.println(userInput); if ("SAIR".equals(userInput)) break; } if (clientIn.ready()) { String msg = clientIn.readLine(); System.out.println(">" + msg); if ("SAIR".equals(msg)) break; } } } catch (IOException e) { System.out.println("Ocorreu um erro ao tentar escutar na porta " + portNumber); System.out.println(e.getMessage()); } } }
Exercício 2
- Utiliza TCP/IP - Orientado a conexão
- Aceita conexão de mais de um cliente por servidor
- Não desperdiça CPU pois emprega threads para evitar um laço de espera ocupada
Download do .java
para o Servidor e para o Cliente:
Cliente
import java.io.*; import java.net.*; public class Aula01_Ex02_Cliente { static class ConexaoServidor implements Runnable { private final Socket socket; private final PrintWriter socketOut; private final BufferedReader socketIn; private final String nick; public ConexaoServidor (Socket socket, String nick) throws IOException { this.socket = socket; this.nick = nick; socketOut = new PrintWriter(socket.getOutputStream(), true); socketIn = new BufferedReader( new InputStreamReader(socket.getInputStream())); } public void enviaMensagem(String msg) { socketOut.println(nick + "> " + msg); } public void run () { try{ while (true) { String msg = socketIn.readLine(); if (msg == null) { System.out.println("Conexão perdida."); System.exit(1); } System.out.println(msg); } } catch (Exception e) { System.out.println(e.getMessage()); } finally { try { socketIn.close(); socketOut.close(); socket.close(); } catch (Exception e) { //já não ha mais o que se fazer } } } } public static void main(String[] args) throws IOException { if (args.length != 3) { System.err.println( "Forma de uso: java Aula01_Ex02_Cliente <end. servidor> <porta> <nick>"); System.exit(1); } String hostName = args[0]; int portNumber = Integer.parseInt(args[1]); String nick = args[2]; try ( Socket socket = new Socket(hostName, portNumber); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)) ) { ConexaoServidor conexaoServidor = new ConexaoServidor(socket, nick); Thread th = new Thread (conexaoServidor); th.setDaemon(true); th.start(); String userInput; while ((userInput = stdIn.readLine()) != null) { if ("SAIR".equals(userInput)) break; conexaoServidor.enviaMensagem(userInput); } } catch (UnknownHostException e) { System.err.println("Endereço desconhecido " + hostName); System.exit(1); } catch (IOException e) { System.err.println("Erro conectanto em: " + hostName); System.exit(1); } } }
Servidor
import java.net.*; import java.io.*; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public class Aula01_Ex02_Servidor { static Set<ConexaoCliente> clientes = ConcurrentHashMap.newKeySet(); static class ConexaoCliente implements Runnable { private final Socket socket; private final PrintWriter clientOut; private final BufferedReader clientIn; public ConexaoCliente (Socket clientSocket) throws IOException { socket = clientSocket; clientOut = new PrintWriter(clientSocket.getOutputStream(), true); clientIn = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); clientes.add(this); } public void enviaMensagem(String msg) { clientOut.println(msg); } public void run () { try{ while (true) { String msg = clientIn.readLine(); if (msg == null || msg.endsWith("SAIR")) break; for (ConexaoCliente conexao : clientes) { if (conexao == this) continue; conexao.enviaMensagem(msg); } System.out.println(msg); } } catch (IOException e) { System.out.println("> Ocorreu um erro com uma conexão:" + e.getMessage()); } finally{ clientes.remove(this); System.out.println("> Cliente desconectado. Conexões ativas: " + clientes.size()); try{clientIn.close(); clientOut.close(); socket.close();} catch (IOException e) { System.out.println("> Ocorreu um erro tentando fechar a conexão:" + e.getMessage()); } } } } public static void main(String[] args) throws IOException { if (args.length != 1) { System.err.println("Forma de uso: java Aula01_Ex02_Servidor <porta>"); System.exit(1); } int portNumber = Integer.parseInt(args[0]); ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0])); while (true) { System.out.println("> Esperando usuários. Conexões ativas: " + clientes.size()); Socket clientSocket = serverSocket.accept(); ConexaoCliente cliente = new ConexaoCliente(clientSocket); new Thread(cliente).start(); System.out.println("> Recebida uma conexão."); } } }
Exercício 3
- Utiliza UDP/IP - Orientado a datagramas
- Ao contrário do exercício 2, não é capaz de manter facilmente uma contagem dos clientes conectados
- Para isto seria necessário implementar um sistema de verificação (essencialmente o que o TCP/IP faz)
- Como este código não implementa o sistema acima, a lista dos clientes conectados nunca é limpa. Em um sistema real essa lista cresceria até o limite da memória
Download do .java
para o Servidor e para o Cliente:
Cliente
import java.io.*; import java.net.*; public class Aula01_Ex03_Cliente { static class ConexaoServidor implements Runnable { private final DatagramSocket socket; public ConexaoServidor (DatagramSocket socket) { this.socket = socket; } public void run () { try{ while (true) { DatagramPacket resposta = new DatagramPacket (new byte[512], 512); socket.receive (resposta); System.out.println (new String(resposta.getData())); } } catch (Exception e) { System.out.println(e.getMessage()); } finally { try { socket.close(); } catch (Exception e) { //já não ha mais o que se fazer } } } } public static void main(String[] args) throws IOException { if (args.length != 3) { System.err.println( "Forma de uso: java Aula01_Ex03_Cliente <end. servidor> <porta> <nick>"); System.exit(1); } String hostName = args[0]; int porta = Integer.parseInt(args[1]); String nick = args[2]; try ( DatagramSocket socket = new DatagramSocket(); BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)) ) { InetAddress addr = InetAddress.getByName(hostName); ConexaoServidor conexaoServidor = new ConexaoServidor(socket); Thread th = new Thread (conexaoServidor); th.setDaemon(true); th.start(); String userInput; while ((userInput = stdIn.readLine()) != null) { if ("SAIR".equals(userInput)) break; byte[] buffer = (nick + "> " + userInput).getBytes(); DatagramPacket datagrama = new DatagramPacket ( buffer, buffer.length, addr, porta); socket.send (datagrama); } } catch (UnknownHostException e) { System.err.println("Endereço desconhecido " + hostName); System.exit(1); } catch (IOException e) { System.err.println("Erro conectanto em: " + hostName); System.exit(1); } } }
Servidor
import java.net.*; import java.io.*; import java.util.*; public class Aula01_Ex03_Servidor { static Set<Cliente> clientes = new HashSet<>(); static class Cliente { InetAddress endereco; int porta; public Cliente (DatagramPacket pkt) { endereco = pkt.getAddress(); porta = pkt.getPort(); } static Cliente atualizaClientes (DatagramPacket pkt) { Cliente ret = new Cliente(pkt); clientes.add(ret); return ret; } public boolean equals(Object o) { return o != null && getClass() == o.getClass() && endereco.equals(((Cliente)o).endereco) && porta == ((Cliente)o).porta; } public int hashCode() { return Objects.hash(endereco, porta); } public void enviaMensagem(byte[] buffer, DatagramSocket socket) throws IOException { DatagramPacket datagrama = new DatagramPacket ( buffer, buffer.length, endereco, porta); socket.send (datagrama); } } public static void main(String[] args) { if (args.length != 1) { System.err.println("Forma de uso: java Aula01_Ex03_Servidor <porta>"); System.exit(1); } int portNumber = Integer.parseInt(args[0]); try( DatagramSocket serverSocket = new DatagramSocket (Integer.parseInt(args[0])); ){ while (true) { System.out.println("> Esperando mensagens."); DatagramPacket msg = new DatagramPacket (new byte[512], 512); serverSocket.receive (msg); System.out.println(new String(msg.getData())); Cliente cliente = Cliente.atualizaClientes(msg); for (Cliente cli: clientes) { if (cli.equals(cliente)) continue; cli.enviaMensagem(msg.getData(), serverSocket); } } } catch (IOException e) { System.out.println("Encerrando conexão."); } } }