A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

PRDS - Programa de Residência em Desenvolvimento de Software Laboratório de Engenharia de Software (LES) da PUC-Rio Carlos Lucena

Apresentações semelhantes


Apresentação em tema: "PRDS - Programa de Residência em Desenvolvimento de Software Laboratório de Engenharia de Software (LES) da PUC-Rio Carlos Lucena"— Transcrição da apresentação:

1 PRDS - Programa de Residência em Desenvolvimento de Software Laboratório de Engenharia de Software (LES) da PUC-Rio Carlos Lucena Rodrigo Paes Gustavo Carvalho Cidiane Lobato

2 2 © LES/PUC-Rio Conteúdo Módulo 1: Java I – 4 horas –Sintaxe –IDE Eclipse Módulo 2: Orientação a Objetos com Java I – 4 horas –Herança –Polimorfismo –Associação –Delegação –Collections Módulo 3: Java II – 8 horas –Manipulação de dados –Persistência JDBC –Sockets Módulo 4: UML – 8 horas –Casos de Uso –Classes –Seqüência Módulo 5: Qualidade de Software I – 4 horas –Teste –Assertiva de execução Módulo 6: Orientação a objetos com Java II – 8 horas –Padrões de projeto –Frameworks

3 3 © LES/PUC-Rio Conteúdo Módulo 7: Java III – 12 horas –Mapeamento OO --> ER –Persistência Hibernate Módulo 8: Desenvolvimento WEB I – 16 horas –Servlets, JSP, Desenvolvimento de taglibs –Arquitetura 3 camadas –MVC básico Módulo 9: Desenvolvimento WEB II – 20 horas –MVC Struts –Internacionalização Módulo 10: Desenvolvimento WEB III – 28 horas –MVC Spring –Testes na camada WEB –Appfuse

4 Manipulação de Dados através de Fluxos Java

5 5 © LES/PUC-Rio Fluxos de Java: Introdução Muitos programas Java interagem com algum repositório de dados. Por ex., dados podem ser armazenados: –em arquivos em uma unidade de disco rígido ou CD-ROM; –nas páginas de um site da Web; –na memória de um computador; –em outro programa. Em Java, dados são recuperados e armazenados usando um sistema de comunicação denominado fluxos. É necessário criar fluxos de entrada para recuperar dados e fluxos de saída para armazená-los.

6 6 © LES/PUC-Rio Fluxos de Java: Introdução Para obter dados, um programa abre um stream em uma fonte de dados (um arquivo, memória, um socket) e lê os dados seqüencialmente. Similarmente, um programa envia dados para um destino abrindo um stream associado ao destino e escrevendo nele seqüencialmente os dados.

7 7 © LES/PUC-Rio Fluxos de Java: Algoritmos Independente da origem e dos tipos de dados, os algoritmos para recuperação (leitura) e armazenamento (escrita) dos dados são basicamente os mesmos: Reading open a stream while more information read information close the stream Writing open a stream while more information write information close the stream

8 8 © LES/PUC-Rio Fluxos de Java: Pacote e Hierarquias O pacote java.io contém uma coleção de classes de fluxos que dão suporte aos algoritmos para leitura e escrita. Portanto, para utilizar fluxos de dados, um programa deve importar o pacote java.io. As classes de fluxos são organizadas em duas hierarquias de classes, baseadas nos tipos de dados (caracteres ou bytes).

9 9 © LES/PUC-Rio Fluxos de Byte: Visão Geral Usados para leitura e escrita de bytes de 8 bits. –Podem incluir dados numéricos, programas executáveis, comunicação na Internet e bytecodes. –Tipicamente são usados para ler e escrever imagens e sons. –Na verdade, qualquer tipo de dado imaginável pode ser (inclusive caracteres!) expresso usando uma série de bytes. Descendem das classes InputStream e OutputStream. –InputStream fornece a API e a implementação parcial para fluxos de entrada (fluxos para leitura de bytes de 8 bits). –OutputStream fornece a API e a implementação parcial para fluxos de saída (fluxos para escrita de bytes de 8 bits). Por ex., ObjectInputStream e ObjectOutputStream são classes usadas para serialização de objetos.

10 10 © LES/PUC-Rio Fluxos de Byte: InputStream Para leitura de arquivos de bytes de 8 bits, usamos a classe FileInputStream.

11 11 © LES/PUC-Rio Fluxos de Byte: OutputStream Para escrita de arquivos de bytes de 8 bits, usamos a classe FileOutputStream.

12 12 © LES/PUC-Rio Fluxos de Caractere: Visão Geral Usados para leitura e escrita de caracteres de 16 bits. –Podem tratar caracteres Unicode, ao passo que fluxos de byte limitam-se ao padrão ISO-Latin-1 (bytes com 8 bits). –Para o tratamento de dados textuais, incluindo arquivos, páginas Web e outros tipos comuns de texto, recomenda-se sempre o uso de fluxos de caratere! Descendem das classes Reader e Writer. –Reader fornece a API e a implementação parcial para fluxos de entrada (fluxos para leitura de caracteres de 16 bits). –Writer fornece a API e a implementação parcial para fluxos de saída (fluxos para escrita de caracteres de 16 bits).

13 13 © LES/PUC-Rio Fluxos de Caracter: Reader

14 14 © LES/PUC-Rio Fluxos de Caracter: Writer

15 15 © LES/PUC-Rio Fluxos de Entrada: Reader e InputStream Reader e InputStream definem APIs similares para caracteres e bytes, respectivamente. Por exemplo, Reader contém os seguintes métodos para leitura de caracteres e arrays de caracteres. –int read() –int read(char cbuf[]) –int read(char cbuf[], int offset, int length) Da mesma forma, InputStream define os mesmos métodos para a leitura de bytes e arrays de bytes: –int read() –int read(byte cbuf[]) –int read(byte cbuf[], int offset, int length)

16 16 © LES/PUC-Rio Fluxos de Entrada: Reader e InputStream No caso de um fluxo de entrada, o primeiro passo é criar um objeto que esteja associado à origem de dados. –Por ex., se a origem for um arquivo em disco rígido, um objeto FileInputStream, poderá ser associado com este arquivo. Uma vez obtido o objeto de fluxo de entrada, é possível ler informações desse fluxo usando métodos do objeto. –FileInputStream inclui um método read() que retorna um byte lido do arquivo. Ao acabar de usar os dados de um fluxo, um procedimento de finalização deve ser chamado. –FileInputStream inclui um método close() para indicar que acabou de usar um arquivo.

17 17 © LES/PUC-Rio Fluxos de Saída: Writer e OutputStream Similarmente… Writer e OutputStream definem APIs similares para caracteres e bytes, respectivamente. Writer contém os seguintes métodos para escrita de caracteres e arrays de caracteres. –int write(int c) –int write(char cbuf[]) –int write(char cbuf[], int offset, int length) OutputStream define os mesmos métodos para a escrita de bytes e arrays de bytes: –int write(int c) –int write(byte cbuf[]) –int write(byte cbuf[], int offset, int length)

18 18 © LES/PUC-Rio Fluxos de Entrada: Writer e OutputStream No caso de um fluxo de saída, é criado primeiro um objeto associado ao destino dos dados. –Tal objeto pode ser criado a partir da classe BufferedWriter, que representa um modo eficiente de criar arquivos de texto. Os dados são então escritos no objeto associado ao destino. –O método BufferedWriter.write() envia caracteres individuais para o fluxo de saída. Assim como é feito com os fluxos de entrada, o fluxo é então finalizado. –O método BufferedWriter.close() é chamado em um fluxo de saída quando não se têm mais informações a enviar.

19 19 © LES/PUC-Rio Fluxos de Arquivo: Exemplo Copy import java.io.*; public class Copy { public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt"); File outputFile = new File("outagain.txt"); FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); }

20 20 © LES/PUC-Rio Fluxos de Arquivo: Exemplo Copy 1.O programa cria os objetos File que representam os arquivos farrago.txt e outagain.txt no sistema. 2.O programa cria fluxos FileReader e FileWriter para os arquivos farrago.txt e outagain.txt. 3.O programa lê o reader enquanto há caracteres no arquivo farrago.txt e escreve tais caracteres no writer. 4.Quando a leitura da entrada termina, o programa fecha o reader e o writer.

21 21 © LES/PUC-Rio Fluxos de Arquivo: Exemplo Copy Saída do programa: uma cópia exata de farrago.txt em um arquivo outagain.txt no mesmo diretório. Portanto, o conteúdo do arquivo outagain.txt é: So she went into the garden to cut a cabbage-leaf, to make an apple-pie; and at the same time a great she-bear, coming up the street, pops its head into the shop. 'What! no soap?' So he died, and she very imprudently married the barber; and there were present the Picninnies, and the Joblillies, and the Garyalies, and the grand Panjandrum himself, with the little round button at top, and they all fell to playing the game of catch as catch can, till the gun powder ran out at the heels of their boots. Samuel Foote

22 22 © LES/PUC-Rio Fluxos de Arquivo: Exemplo CopyBytes import java.io.*; public class CopyBytes { public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt"); File outputFile = new File("outagain.txt"); FileInputStream in = new FileInputStream(inputFile); FileOutputStream out = new FileOutputStream(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); }

23 23 © LES/PUC-Rio import java.io.*; public class ReadBytes { public static void main(String[] arguments) { try { FileInputStream file = new FileInputStream("class.dat"); boolean eof = false; int count = 0; while (!eof) { int input = file.read(); System.out.print(input + " "); if (input == -1) eof = true; else count++; } file.close(); System.out.println("\nBytes read: " + count); } catch (IOException e) { System.out.println("Error -- " + e.toString()); } Fluxos de Arquivo: Exemplo ReadBytes

24 24 © LES/PUC-Rio Fluxos de Arquivo: Exemplo ReadBytes Bytes read: 717

25 25 © LES/PUC-Rio import java.io.*; public class WriteBytes { public static void main(String[] arguments) { int[] data = { 71, 73, 70, 56, 57, 97, 15, 0, 15, 0, 128, 0, 0, 255, 255, 255, 0, 0, 0, 44, 0, 0, 0, 0, 15, 0, 15, 0, 0, 2, 33, 132, 127, 161, 200, 185, 205, 84, 128, 241, 81, 35, 175, 155, 26, 228, 254, 105, 33, 102, 121, 165, 201, 145, 169, 154, 142, 172, 116, 162, 240, 90, 197, 5, 0, 59 }; try { FileOutputStream file = new FileOutputStream("pic.gif"); for (int i = 0; i < data.length; i++) file.write(data[i]); file.close(); } catch (IOException e) { System.out.println("Error -- " + e.toString()); } Fluxos de Arquivo: Exemplo WriteBytes

26 26 © LES/PUC-Rio Fluxos de Saída: Saída do Exemplo

27 27 © LES/PUC-Rio Fluxos de Seqüência: Exemplo O SequenceInputStream cria um único fluxo de entrada a partir de múltiplos fluxos de entrada. O programa Concatenate usa um SequenceInputStream a fim de concatenar arquivos seqüencialmente na ordem em que são especificados na linha de comando.

28 28 © LES/PUC-Rio Fluxos de Seqüência: Exemplo

29 29 © LES/PUC-Rio Fluxos de Seqüência: Exemplo ListOfFiles implementa a interface Enumeration. Após a criação do SequenceInputStream, o método main lê do fluxo um byte a cada vez. Para ler o InputStream de uma nova fonte, SequenceInputStream chama o nextElement() do objeto Enumeration a fim de obter o próximo InputStream.

30 30 © LES/PUC-Rio Fluxos Pipe: Introdução Pipes: são usados para fazer um canal entre a saída de uma thread e a entrada de outra. PipedReader e PipedWriter (caracteres), bem como PipedInputStream e PipedOutputStream (bytes), implementam os componentes de entrada e saída de pipes. Por que pipes são úteis?

31 31 © LES/PUC-Rio Fluxos Pipe: Exemplo Considere uma classe que implementa vários métodos de manipulação de strings, tais como ordenação e reversão de caracteres em uma string. Seria interessante se a saída de um destes métodos pudesse ser usada como a entrada para outro de forma que uma série de chamadas de método pudesse ser usada como uma função de alto-nível. Por ex., se fosse necessário reverter cada palavra em uma lista, ordenar as palavras e então reverter novamente cada palavra a fim de criar uma lista de palavras rhyming...

32 32 © LES/PUC-Rio Fluxos Pipe: Exemplo Sem fluxos pipe, o programa teria que armazenar os resultados em algum lugar (em um arquivo ou na memória) entre cada passo. Com fluxos pipe, a saída de um método poderia ser canalizada para a entrada do próximo método.

33 33 © LES/PUC-Rio Fluxos Pipe: Exemplo

34 34 © LES/PUC-Rio Fluxos Pipe: Exemplo

35 35 © LES/PUC-Rio Fluxos Pipe: Exemplo

36 36 © LES/PUC-Rio Fluxos Pipe: Exemplo

37 37 © LES/PUC-Rio Fluxos Pipe: Exemplo O programa usa PipedReader e PipedWriter para conectar a entrada e saída dos métodos reverse e sort a fim de criar uma lista de palavras rhyming. A chamada mais interna ao método reverse recebe um FileReader, fluxo aberto no arquivo words.txt, que contém uma lista de palavras. O retorno de reverse é passado ao sort, que, por sua vez, tem seu retorno passado para a chamada mais externa ao método reverse.

38 38 © LES/PUC-Rio Fluxos Pipe: Exemplo No método reverse, as linhas de criação dos extremos de um pipe – um PipedWriter e um PipedReader – fazem também o PipedReader ouvir" o PipedWriter. O método reverse inicia um ReverseThread, que escreve sua saída no PipedWriter, mas retorna o PipedReader (ouvindo o PipedWriter!) ao chamador.

39 39 © LES/PUC-Rio Fluxos Pipe: Exemplo O método reverse contém outros comandos interessantes: BufferedReader in = new BufferedReader(source);... PrintWriter out = new PrintWriter(pipeOut); O programa lê de BufferedReader, que por sua vez lê de source, um fluxo Reader. –O programa faz isso para se utilizar do conveniente método readLine de BufferedReader. –Similarmente, a escrita do PipedWriter é lida por PrintWriter para que o programa possa usar o conveniente método println. A concatenção de fluxos é freqüente, pois permite a combinação de características dos vários tipos de fluxos.

40 40 © LES/PUC-Rio Exercícios Usando fluxos de byte (BufferedInputStream) e fluxos de dados primitivos (DataInputStream) para filtrar dados (FilterInputStream), implemente um programa WritePrimes que escreve os primeiros 400 números primos como inteiros em um arquivo chamado 400primes.dat. Implemente também um programa ReadPrimes que lê os inteiros do arquivo WritePrimes e os apresenta.

41 Persistência usando JDBC

42 42 © LES/PUC-Rio Introdução JDBC (Java Database Connectivity): biblioteca de classes Java para conexão com bancos de dados (BDs) relacionais desenvolvidos por Microsoft, Sybase, Oracle, Informix, etc. Driver: ponte para um banco de dado relacional fornecido por uma empresa. Driver JDBC: ponte entre o JDBC e um banco de dado relacional fornecido por uma empresa. Gerenciador de Drivers: controla os drivers exigidos para o acesso aos registros de BDs, o que permite a independência de JDBC dos formatos BDs.

43 43 © LES/PUC-Rio Introdução Usando um driver JDBC como ponte para a fonte de dados, é possível recuperar e armazenar dados diretamente da linguagem Java. A biblioteca JDBC também um driver especial que a liga a outro padrão de conectividade de BDs chamado ODBC. ODBC: biblioteca da Microsoft para o acesso a BDs SQL; é gerenciado pelo ODBC Data Source Administrator. Ponte JDBC-ODBC: permite a conversão de chamadas JDBC para chamadas ODBC.

44 44 © LES/PUC-Rio Introdução Start -> Settings -> Control Panel -> ODBC Data Sources

45 45 © LES/PUC-Rio Visão Geral Usando JDBC (com ou sem ODBC), não há necessidade de adaptação a formatos específicos de BDs, porque: –existem drivers que fazerm o acesso direto aos BDs; –a linguagem SQL (padrão!) é utilizada no código. O JDBC inclui classes para cada uma das tarefas que costumam ser associadas à utilização de BDs: –estabelecimento de uma conexão com um banco de dados; –criação de uma consulta usando SQL; –execução da consulta SQL no banco de dados; –exibição dos registros resultantes. Portanto, classes que usam JDBC seguem o conhecido modelo de programação com instruções SQL.

46 46 © LES/PUC-Rio Visão Geral Na configuração de dados, porém, são possíveis duas alternativas: a ponte JDBC-ODBC ou um driver JDBC. Para usar a ponte JDBC-ODBC, é necessário: –o driver JDBC-ODBC incluído com a linguagem Java 2: sun.jdbc.odbc.JdbcOdbcDriver; –um driver ODBC; –uma fonte de dados ODBC associada ao driver anterior usando o software ODBC Data Source Administrator. Para usar um driver JDBC, é necessário: –obter e instalar o driver (não está incluído em Java!); –associar uma fonte de dados ao driver JDBC.

47 47 © LES/PUC-Rio Usando JDBC-OBDC: Fontes de Dados Todas as fontes de dados ODBC devem receber um nome descritivo curto. Este nome é usado em Java para estabelecer uma conexão com o banco de dados a que a fonte se refere.

48 48 © LES/PUC-Rio Usando JDBC-OBDC: Fontes de Dados

49 49 © LES/PUC-Rio Usando JDBC-OBDC: Fontes de Dados

50 50 © LES/PUC-Rio Usando JDBC-OBDC: Fontes de Dados

51 51 © LES/PUC-Rio Usando JDBC-OBDC: Fontes de Dados

52 52 © LES/PUC-Rio Usando JDBC-OBDC: Fontes de Dados

53 53 © LES/PUC-Rio Usando JDBC-OBDC: Exemplo

54 54 © LES/PUC-Rio Usando JDBC-OBDC: Exemplo Entrada do programa: Poland Saída do programa:

55 55 © LES/PUC-Rio Usando um Driver JDBC: Fontes de Dados Alguns drivers JDBC estão disponíveis para avaliação. O JDataConnectServer da NetDirect está disponível para download de teste a partir do endereço –http://www.j-netdirect.com/http://www.j-netdirect.com/ O JDataConnectServer usa o ODBC Data Source Administrator para criar uma nova fonte de dados associada a um banco de dados.

56 56 © LES/PUC-Rio Usando um Driver JDBC: Exemplo

57 57 © LES/PUC-Rio Usando um Driver JDBC: Exemplo Antes que o programa seja executado com êxito, o JDataConnectServer precisa ser iniciado. A referência a localhost:1150 significa que: –localhost é o nome da máquina que atua como servidor (a máquina local, neste caso); –1150 é o número de porta padrão em que o servidor JDataConnect é executado. O JDataConnectServer pode ser usado em servidores remotos na Internet, de modo que localhost poderia ser substituído por um endereço na Internet.

58 58 © LES/PUC-Rio JDBC: Carregando Drivers Se a ponte JDBC-ODBC é usada, a seguinte linha de código carrega o driver: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); No caso de um driver JDBC, a documentação indica o nome a ser usado. Se o nome do driver é jdbc.DriverXYZ, então a seguinte linha carrega o driver: Class.forName("jdbc.DriverXYZ"); Não é necessário criar uma instância do driver, porque a chamada Class.forName faz isso automaticamente. Após o carregamento, o driver está disponível para efetuar conexões com um BD.

59 59 © LES/PUC-Rio JDBC: Estabelecendo a conexão A forma geral para o estabelecimento de uma conexão é: Connection con = DriverManager.getConnection(url, "myLogin", "myPassword"); Se a ponte JDBC-ODBC é usada, a url começa por jdbc:odbc:. O resto da url é o nome da fonte de dados. Se uma fonte ODBC chamada Fred é usada, a url deve ser jdbc:odbc:Fred. Em "myLogin, é colocado o nome usado para logar no BD; em myPassword, é colocada a senha. Se o nome e a senha são Fernanda e J8, as linhas a seguir estabelecem uma conexão: String url = "jdbc:odbc:Fred"; Connection con = DriverManager.getConnection(url, "Fernanda", "J8");

60 60 © LES/PUC-Rio JDBC: Estabelecendo a conexão Se um driver JDBC é usado, a documentação indica qual subprotocolo usar, isto é, o que colocar após jdbc: na url. Se acme é o subprotocolo, a url será jdbc:acme:. A documentação fornece outras diretivas se necessário. A última parte da url identifica a fonte de dados. O retorno do método DriverManager.getConnection é uma conexão aberta para a criação de comandos JDBC, os quais contêm instruções SQL a serem efetuadas sobre um BD.

61 61 © LES/PUC-Rio JDBC: Criando comandos Um objeto Statement pode enviar um comando SQL ao gerenciador de BD. Para criar um objeto Statement, é necessária uma instância de uma conexão ativa. Na linha a seguir, um objeto Connection chamado con é usado para criar um comando Statement stmt: Statement stmt = con.createStatement(); Após a criação de um objeto Statement, deve ser executado sobre ele o comando SQL apropriado. Para um comando SELECT, o método de Statement usado é executeQuery. Para comandos que criam ou modificam tabelas, o método a usar é executeUpdate. Por exemplo: createTableCoffees = "CREATE TABLE COFFEES " + "(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " + "SALES INTEGER, TOTAL INTEGER); stmt.executeUpdate(createTableCoffees);

62 62 © LES/PUC-Rio JDBC: Recuperando valores JDBC retorna o resultado de um comando em um objeto ResultSet. A linha a seguir declara o objeto ResultSet rs e assinala o resultado do comando stmt a rs: ResultSet rs = stmt.executeQuery( "SELECT COF_NAME, PRICE FROM COFFEES"); O objeto ResultSet rs contém linhas de cafés e preços. O método next move o cursor no objeto para a próxima linha. Sucessivas invocações de next movem o cursor uma linha por vez do início ao fim de rs.

63 63 © LES/PUC-Rio JDBC: Recuperando valores O método getXXX recupera o valor de cada coluna. Por exemplo, a primeira coluna em cada linha de rs é COF_NAME, que armazena um valor de tipo SQL VARCHAR. O método para recuperação de um VARCHAR é getString. A segunda coluna armazena um valor de tipo SQL FLOAT. O método para recuperação de valores FLOAT é getFloat. A seguinte linha de código acessa os valores armazenados na linha corrente de rs e imprime cada linha com o nome seguido por três espaços e o preço. String query = "SELECT COF_NAME, PRICE FROM COFFEES"; ResultSet rs = stmt.executeQuery(query); while (rs.next()) { String s = rs.getString("COF_NAME"); float n = rs.getFloat("PRICE"); System.out.println(s + " " + n); }

64 64 © LES/PUC-Rio JDBC: Resumo

65 65 © LES/PUC-Rio Exercícios Implemente um programa que usa a biblioteca JDBC para: –estabelecer uma conexão com uma fonte de dados; –criar tabelas em um banco de dados associado à fonte; –inserir dados nos campos das tabelas criadas; –executar consultas no banco de dados usando SQL; –exibir os registros recuperados através de consulta. Para fazer o exercício, use o tutorial da Sun sobre JDBC.

66 Sockets

67 67 © LES/PUC-Rio Protocolos de Redes Computadores na Internet se comunicam uns com os outros usando ou o Transmission Control Protocol (TCP) ou o User Datagram Protocol (UDP).

68 68 © LES/PUC-Rio Protocolos em Java: TCP e UDP A programação Java se dá na camada de aplicação. Tipicamente, não é necessário conhecer detalhes internos da camada de transporte, que usa TCP e UDP. Em vez disso, o programador Java se utiliza das classes disponíveis no pacote java.net, que provêem comunicação em rede encapsulando detalhes dos protocolos. Contudo, para saber quais classes Java usar, é necessário entender as diferenças entre TCP e UDP.

69 69 © LES/PUC-Rio Características do TCP Aplicações que precisam se comunicar com confiabilidade: –estabelecem uma conexão e –enviam os dados uma à outra através da conexão. Isto é análogo ao serviço de chamadas telefônicas. Como uma companhia telefônica, o TCP garante que: –os dados enviados a partir de um extremo efetivamente chegam no outro extremo da conexão e, além disso, –na mesma ordem em que foram enviados. Portanto, fornece um canal ponto a ponto para aplicações que requerem comunicação confiável.

70 70 © LES/PUC-Rio Aplicações TCP O Hypertext Transfer Protocol (HTTP) e o File Transfer Protocol (FTP) são aplicações que requerem confiabilidade. –A ordem em que os dados são enviados e recebidos é crítica para o sucesso dessas aplicações. –Por exemplo, quando o HTTP é usado para ler de uma URL, os dados devem ser recebidos na ordem em que são enviados. –De outra forma, o resultado é um HTML mal formatado, um arquivo zip corrompido ou outras informações inválidas. Portanto, TCP é um protocolo baseado em conexão que provê um fluxo de dados confiável entre dois computadores.

71 71 © LES/PUC-Rio Características do UDP Permite comunicação sem confiabilidade entre aplicações. UDP não é baseado em conexão como o TCP. Ao contrário, envia pacotes de dados independentes, chamados datagramas, de uma aplicação à outra. Isto é análogo ao serviço de correio: a ordem de entrega não é importante, pois cada mensagem é independente das outras. Também não há garantia de entrega.

72 72 © LES/PUC-Rio Aplicações UDP Um servidor de relógio é uma aplicação que envia a hora atual para os clientes que requisitam tal informação. –Se o cliente perde um pacote, não faz sentido reenviá-lo. –A confiabilidade do TCP é desnecessária, porque pode diminuir a performance e a utilidade do serviço. Outro exemplo é o comando ping, que testa a comunicação entre dois programas na rede. –Ping não se importa de enviar/receber pacotes quebrados ou fora de ordem para determinar se a conexão é ou não boa. –Um canal confiável invalidaria este serviço. Portanto, UDP é um protocolo que envia pacotes de dados independentes entre aplicações sem confiabilidade.

73 73 © LES/PUC-Rio Conceito de Portas Um computador possui uma única conexão física em uma rede. Todos os dados destinados para um computador chegam através desta conexão. Contudo, os dados podem ter sido enviados para aplicações diferentes. Tais dados são associados a uma aplicação específica através do uso de portas. Portanto, os dados têm seus destinos identificados através do par de identificadores relativos ao computador e à porta. –O endereço do computador é o seu IP, com 32 bits. –Uma porta é identificada por um número de 16 bits, usado por TCP e UDP para entregar dados à aplicação correta.

74 74 © LES/PUC-Rio Portas no TCP Usando TCP, uma aplicação servidor cria um socket para um número de porta específico. Criar o socket significa registrar a aplicação servidor no sistema para receber dados destinados a uma porta através de uma comunicação baseada em conexão.

75 75 © LES/PUC-Rio Portas no UDP Usando UDP, o pacote de datagramas contém o número da porta a que os dados são destinados; o UDP efetua então o roteamento para entregar o pacote à aplicação correta.

76 76 © LES/PUC-Rio Número de Portas Números de portas variam de uma faixa de 0 a porque as portas são representadas por números de 16 bits. Os números de portas variando de 0 a 1023 são restritas; elas são reservadas para uso de serviços conhecidos como HTTP e FTP e outros serviços de sistema. As aplicações não devem utilizar os números de portas restritas aos serviços bem conhecidos.

77 77 © LES/PUC-Rio Descrição de Sockets Um servidor roda em um computador específico e possui um socket associado a um número de porta específico: –no lado do servidor, o servidor apenas espera, ouvindo no socket possíveis requisições de clientes; –no lado do cliente, o cliente sabe o nome da máquina do servidor e o número da porta na qual o servidor está conectado. O cliente tenta estabelecer uma conexão através de uma requisição.

78 78 © LES/PUC-Rio Descrição de Sockets Se tudo está OK, o servidor aceita a conexão. –O servidor obtém um novo socket associado à mesma porta. –Ele usa o novo socket de tal maneira que possa continuar a ouvir no socket original as requisições de clientes enquanto atende às necessidades do cliente conectado no novo socket. Se a conexão é aceita, um socket é criado do lado do cliente e pode ser usado para a comunicação com o servidor.

79 79 © LES/PUC-Rio Descrição de Sockets Formalizando: socket é um ponto extremo de uma comunicação bilateral entre dois programas sendo executados em uma rede. Exemplo: implementação de EchoClient, que se conecta ao servidor Echo. Este serviço está disponível em uma rede através da porta 7 e possui a função de receber dados de um cliente e enviá-los de volta.

80 80 © LES/PUC-Rio Exemplo de Cliente usando Socket

81 81 © LES/PUC-Rio Exemplo de Cliente usando Socket

82 82 © LES/PUC-Rio Exemplo de Cliente usando Socket EchoClient é um programa trivial porque o servidor Echo implementa um protocolo simples. Programas que ouvem servidores HTTP são bem mais complexos. Contudo, o esqueleto básico de um cliente é: 1.abrir um socket; 2.abrir fluxos de entrada e saída no socket; 3.ler e escrever nos fluxos de acordo com protocolo do servidor; 4.fechar os fluxos; 5.fechar o socket. –Somente o passo 3 difere de cliente para cliente, dependendo do servidor.

83 83 © LES/PUC-Rio Servidor e Cliente usando Sockets

84 84 © LES/PUC-Rio Servidor e Cliente usando Sockets

85 85 © LES/PUC-Rio Servidor e Cliente usando Sockets

86 86 © LES/PUC-Rio Servidor e Cliente usando Sockets

87 87 © LES/PUC-Rio Servidor e Cliente usando Sockets

88 88 © LES/PUC-Rio Servidor e Cliente usando Sockets

89 89 © LES/PUC-Rio Exercícios Para manter a simplicidade do exemplo KnockKnockServer, o servidor foi projetado para ouvir e tratar apenas uma única requisição de conexão. Contudo, o servidor deve ser capaz de tratar múltiplas requisições simultaneamente. Neste caso, deve ser mantida uma fila de requisições, de tal maneira que o servidor possa tratá-las seqüencialmente. Reimplemente o servidor KnockKnockServer para a escuta e tratamento de múltiplas requisições simultaneamente (tutorial da Sun: use threads!).

90 90 © LES/PUC-Rio Referências [1] Tutorial da Sun Microsystems. [2] Cadenhead, Rogers; Lemay, Laura. Java 2: professional reference. Rio de Janeiro, Campus, 2001.


Carregar ppt "PRDS - Programa de Residência em Desenvolvimento de Software Laboratório de Engenharia de Software (LES) da PUC-Rio Carlos Lucena"

Apresentações semelhantes


Anúncios Google