Вы находитесь на странице: 1из 11

SISTEMAS DISTRIBUDOS SOCKETS

Prof. Gregorio Perez Peiro


gregorio@uninove.br

ROTEIRO

Introduo aos Soquetes


Threads - prof. Gregorio Perez Peiro

Uma viso mais detalhada Interfaces Bsicas pacote java.util.concurrent

Criao do Servidor Criao do Cliente

Uma aplicao de Eco Uma aplicao de Bate Papo (chat)

INTRODUO

Conexes URLs (Uniform Resource Locator) provem um mecanismo de alto nvel que permite localizar e acessar um recurso disponvel em uma rede atravs de um protocolo ( http, ftp, ...) e do endereo de um servidor Aplicaes Cliente / Servidor requerem uma comunicao de rede de mais baixo nvel confivel para que toda informao que seja enviada pelo servidor chegue ao cliente de maneira correta O protocolo TCP (Transmission Control Protocol) prov um canal de comunicao ponto a ponto confivel para aplicaes cliente / servidor se comunicarem atravs da Internet

Threads - prof. Gregorio Perez Peiro

INTRODUO

Para se comunicar atravs do protocolo TCP , o cliente e o servidor estabelecem uma conexo entre si ligando um soquete (socket) em cada extremidade da conexo e definindo mtodos de leitura e escrita para estes soquetes Tipicamente, um servidor executando em um computador especfico possui um soquete confinado uma porta especfica que permanece atento a espera de que algum cliente faa uma requisio
Servidor Porta #
soquete

Threads - prof. Gregorio Perez Peiro

INTRODUO

Do lado do cliente, este deve conhecer o identificador da mquina hospedeira do servidor e o nmero da porta em que o servidor aguarda comunicao Para efetuar a requisio, o cliente tenta localizar o aplicativo servidor atravs da porta definida na mquina hospedeira, se identificando ao servidor e estabelecendo uma ligao esta porta local
Porta #
Servidor Porta # soquete

Threads - prof. Gregorio Perez Peiro

Cliente
5

INTRODUO

Estando disponvel, o servidor aceita a conexo e recebe um novo soquete confinado mesma porta local, alm de determinar um ligao remota com o endereo e porta do cliente Do lado do cliente, se a conexo aceita, um soquete criado e pode ser utilizado para estabelecer comunicao com o servidor permitindo a leitura e escrita atravs de seus soquetes

O novo soquete necessrio para que o servidor possa continuar atento novas requisies enquanto o soquete original atende ao cliente conectado. Isto anlogo ao correio corporativo - cada pessoa dentro de uma companhia compartilha o mesmo endereo, mas a carta encaminhada dentro da companhia pelo nome da pessoa.

Threads - prof. Gregorio Perez Peiro

Porta #
soquete Servidor Porta # soquete soquete

Cliente
6

Introduo

SOCKETS

Um soquete (socket) um terminal de comunicao de dupla direo que liga dois programas executando em rede Um soquete limitado um nmero de porta para que a camada TCP possa identificar o aplicativo para o qual as informaes devem ser enviadas Um terminal uma combinao de endereo IP e um nmero de porta Cada conexo TCP pode ser identificada unicamente pela combinao de seus dois terminais

Um soquete (socket) nada mais que uma abstrao computacional que mapeia diretamente uma porta de comunicao (TCP ou UDP) e mais um endereo de rede. Com esse conceito possvel identificar unicamente um aplicativo ou servidor na rede de comunicao IP.

Threads - prof. Gregorio Perez Peiro

SOCKETS EM JAVA

A linguagem Java possui um conjunto de classes (pacote java.net) que permite implementar conexes em uma rede, porm mantendo a independncia da plataforma

A classe Socket implementa a conexo entre o aplicativo Java e os demais aplicativos da rede escondendo detalhes particulares dos sistemas A classe ServerSocket implementa soquetes que os servidores podem utilizar para atentar e aceitar conexes dos clientes

A classe Socket define uma implementao dependente da plataforma, necessria para o reconhecimento do sistema utilizado, mas esconde os detalhes do sistema em particular do programa Java. Desta forma, a comunicao sobre a rede procede de maneira independente das plataformas utilizadas.

Threads - prof. Gregorio Perez Peiro

Se o objetivo for uma conexo para Web, as classe URL, URLConnection e URLEncoder fornecem uma conexo de mais alto nvel que as classes de soquetes sendo, provavelmente, mais apropriadas
8

Sockets

EXEMPLO: SERVIDOR DE ECO

Um servidor de Eco simplesmente recebe dados de um cliente e os envia de volta

Threads - prof. Gregorio Perez Peiro

Servidor

Recebe uma String do cliente (que representam dados) Converte a String para maisculas Devolve a String convertida para o cliente

Cliente

Espera o usurio digitar uma linha (armazenada em uma String) Envia esses dados para o servidor Recebe os dados de volta do servidor Mostra no monitor

Aplicativo de Eco

SERVIDOR
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class ServidorEco { public static void main ( String [] args ) { try { ServerSocket soquete = new ServerSocket( 2000 );

Threads - prof. Gregorio Perez Peiro

Linhas 1 a 5: Classes (e seus respectivos pacotes) do Java necessrias para criar um servidor bsico Linha 11: Criao de um soquete que fica escutando a porta 2000

10

continua ...

Aplicativo de Eco

SERVIDOR
Threads - prof. Gregorio Perez Peiro

14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.

while ( true ) { System.out.print( Esperando conexo... ); Socket conexao = soquete .accept(); System.out.println( Conectado ! ); Scanner entrada = new Scanner( conexao.getInputStream( ) ); PrintStream saida = new PrintStream( conexao.getOutputStream( ) ); String linha = entrada.nextLine(); continua ...

Linhas 16 a 20: Aguarda algum se conectar. A execuo do servidor fica bloqueada na chamada do mtodo accept() da classe ServerSocket. Quando algum se conectar ao servidor, o mtodo desbloqueia e retorna com um objeto da classe Socket, que uma porta da comunicao. Linha 22 a 26: Criao dos objetos de controle do fluxo de comunicao para entrada ( getInputStream( ) ) e sada ( getOutputStream( ) ). Linha 28: Aguarda a insero de alguma entrada de dado a partir do cliente e armazena em uma String.

11

Aplicativo de Eco

SERVIDOR
Threads - prof. Gregorio Perez Peiro

Se a entrada recebida for null significa que o objeto no existe, o que ocorre quando a conexo interrompida.
while ( linha != null &&

30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.

!( linha.trim( ).equals( ) ) ) { saida.println( Eco: + linha.toUpperCase( ) ); linha = entrada.nextLine(); } conexao.close( ); } // fecha o while } catch ( IOException erro ) { System.out.println( "IOException: " + erro ); } } } // fecha o try ... catch // fecha o main // fecha a calsse do servidor Eco

Linhas 31 a 34: Enquanto a entrada recebida no for nula ou vazia, altera a entrada para maisculas ( toUpperCase( ) ) e envia de volta para o cliente. Linha 35: Aps devolver a linha para o Cliente, aguarda por uma nova entrada Linha 37: Se o cliente enviou linha em branco, as linhas 31 a 36 no sero executadas e a conexo ser encerrada. Neste caso, o servidor aguardar nova conexo.

12

Linha 39: A clusula catch captura erros de entrada e sada (I/O) e os exibe.

Aplicativo de Eco

CLIENTE
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

Similar ao servidor, o cliente deve possuir um objeto do tipo Socket para conexo (Linha 9).
continua ...
Threads - prof. Gregorio Perez Peiro

import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; public class ClienteEco { public static void main(String args[]) { try {

A conexo deve conhecer o endereo ou o IP da mquina com quem se quer conectar, alm da porta da aplicao. Em nosso exemplo, usamos o IP da mquina local (127.0.0.1) e a porta da aplicao: porta 2000 do ServidorEco . Novamente, devem ser criados os objetos para o controle do fluxo de comunicao (Linhas 11 a 14) e objetos para leitura e armazenamento dos dados inseridos por teclado (Linhas 15 e 16).

Socket conexao = new Socket( 127.0.0.1, 2000 ); Scanner entrada = new Scanner( conexao.getInputStream ( ) ); PrintStream saida = new PrintStream( conexao.getOutputStream()); String linha; Scanner teclado = new Scanner( System.in );
13

Aplicativo de Eco

CLIENTE
14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 30. 31.

while ( true ) { System.out.print( Digite algo >> ); linha = teclado.nextLine( ); saida.println( linha ); if ( !entrada.hasNext( ) ) { System.out.println( Conexao encerrada! ); break; } linha = entrada.nextLine( ); System.out.println( linha ); } } catch ( IOException erro ) { System.out.println( IOException: + erro ); } } } // fecha o try ... catch // fecha o main // fecha a calsse do servidor Eco

Threads - prof. Gregorio Perez Peiro

Enquanto algo for escrito no aplicativo cliente, o cliente enviar dados ao servidor (linha 17) e receber o retorno do servidor (linha 22) que ser exibido (linha 23). Linhas 18 a 21: Se no houver dados a conexo ser encerrada terminando o aplicativo Linha 31: Novamente, a clusula catch captura erros de entrada e sada (I/O) e os exibe.

14

Aplicativo de Eco

RESULTADO

Servidor

Esperando conexo ...

Conectado ! Esperando conexo ...

O servidor executa e espera um cliente se conectar. Quando um cliente executa, ele localiza o servidor e solicita conexo. Ao ser conectado, permite que o cliente envie uma frase que ser convertida para maisculas no servidor e enviada de volta ao cliente que a exibe. Se o cliente enviar uma linha em branco a conexo deste cliente com o servidor ser encerrada e o servidor aguardar por novo cliente.

Threads - prof. Gregorio Perez Peiro

Cliente

Digite algo >> sistemas distribuidos Eco: SISTEMAS DISTRIBUIDOS Digite algo >>

Conexao encerrada!

15

Aplicativo de Eco

PROBLEMA

Apenas um cliente por vez pode se conectar ao servidor Suponha agora que em vez de um servidor de eco, tivssemos um servidor de bate papo (chat) em que vrios clientes tenham que estar conectados ao servidor ao mesmo tempo

Threads - prof. Gregorio Perez Peiro

Para que isso possa ocorrer, a soluo usar a Thread

O processo de execuo inicial dispara outro processo de execuo a cada novo cliente e fica esperando por novas conexes

16

Sockets e Trheads

APLICATIVO DE BATE PAPO CRIANDO UM CHAT

O servidor de bate papo deve aceitar conexo de um cliente, disparar uma thread para atender esse cliente e esperar por conexo de um novo cliente
Cliente
Porta # Servidor soquete
Porta #

soquete

soquete

soquete soquete
... Cliente Porta #

Cliente

Porta #
soquete

A thread que atende um cliente especfico deve esperar que este envie uma mensagem e replicar esta mensagem para todos os clientes conectados. Quando esse cliente desconectar a thread deve avisar a todos os clientes conectados que isso ocorreu, portanto, necessrio que o servidor guarde em um vetor, todos os clientes conectados num dado instante

Threads - prof. Gregorio Perez Peiro

Cliente Porta #

soquete

soquete

17

Aplicativo de Chat

SERVIDOR
1. 2. 3. 4. 5. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.

import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; import java.util.Vector; public class ServidorBatePapo implements Runnable { private static Vector clientes = new Vector(); private Socket conexao; private String identidade; // socket deste cliente // nome deste cliente

Threads - prof. Gregorio Perez Peiro

public ServidorBatePapo( Socket soquete ) { conexao = soquete; } continua ...


18

Aplicativo de Chat

SERVIDOR
Threads - prof. Gregorio Perez Peiro

Linhas 20 e 22: Criao dos objetos controlam fluxo de comunicao Linha 25: Recebe cliente uma identidade

que do

17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32.

public void run() { try { Scanner entrada = new Scanner( conexao.getInputStream( ) ); PrintStream saida = new PrintStream( conexao.getOutputStream( ) ); identidade = entrada.nextLine( ); if ( identidade == null ) { return; } clientes.add( saida ); continua ...

Linha 27: Verifica se a identidade recebida valida. Quando a conexo interrompida, a string null e a execuo para este cliente deve ser terminar. Linha 31: Uma vez que existe um cliente conhecido aloca-se o fluxo de sada para esse cliente no vetor de clientes conectados. clientes objeto compartilhado por vrias threads. De acordo com o manual da API, os mtodos so sincronizados, portanto, no h problemas de acessos simultneos.

19

Aplicativo de Chat

SERVIDOR
Threads - prof. Gregorio Perez Peiro

32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47.

String linha = entrada.nextLine(); while ( linha != null && !( linha.trim( ).equals( ) ) ) { sendToAll( saida, " disse: ", linha ); linha = entrada.nextLine(); } sendToAll( saida, " saiu ", do chat! ); clientes.remove( saida ); conexao.close( ); } catch ( IOException erro ) { System.out.println( "IOException: " + erro ); } } continua ...

Linhas 34 a 38: Loop principal: esperando por alguma string do cliente. Quando recebe, envia a todos os conectados at que o cliente envie linha em branco. Se linha recebida no for null (conexo interrompida), pode-se envi-la a todos os clientes conectados. O mtodo sendToAll() foi criado por ns (na prxima pgina) com este propsito. Depois de enviar a mensagem, o servidor aguarda nova entrada. Linhas 39 a 41: Uma vez que o cliente enviou linha em branco, retira-se fluxo de sada do vetor de clientes e fecha-se conexo.

20

Linha 43: Caso ocorra alguma exceo de E/S, mostre qual foi.

Aplicativo de Chat

SERVIDOR
Threads - prof. Gregorio Perez Peiro

47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61.

public void sendToAll ( PrintStream saida, String acao, String linha ) throws IOException { for ( int i = 0; i < clientes.size( ); i++){ PrintStream chat = (PrintStream) clientes.get( i ); if ( chat != saida ) { chat.println( identidade + acao + linha ); } } } }

mtodo sendToAll() envia uma mensagem para todos, menos para ele mesmo.

Linha 53: obtm o fluxo de sada de um dos clientes. Linha 56: envia para todos, menos para o prprio usurio (saida).

21

Aplicativo de Chat

APLICATIVO SERVIDOR
Threads - prof. Gregorio Perez Peiro

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class AplServidor { public static void main(String[] args) { try { ServerSocket ss = new ServerSocket( 2222 ); ExecutorService aplicativoServidor = Executors.newFixedThreadPool( 4 );

22

continua ...

Linha 10: O servidor necessita uma porta para conexo que, neste exemplo, foi escolhida com sendo 2222 (uma porta livre escolhida aleatoriamente). Linha 12: O servidor pode trabalhar com uma quantidade virtualmente ilimitada de clientes, porm isto pode limitar o desempenho do sistema ou dificultar a aplicao de regras de segurana. Uma soluo que pode ser utilizada em sistemas como salas de bate papo a limitao de clientes (ou threads) que o servidor atende em determinado instante. Como j foi visto, esta limitao pode ser obtida com o mtodo newFixedThreadPool() da classe Executors. Neste exemplo, limitamos a quantidade de clientes a quatro (4 linha 13). Apesar da limitao da quantidade de clientes, se um cliente adicional tentar se conectar, nenhuma mensagem ser enviada a este cliente que permanecer em espera sem nenhum retorno at que algum dos clientes saia do conjunto ativo no servidor. Em um programa real de bate papo, isto precisa ser solucionado. Linhas 16 a 23: A estrutura de repetio principal aguarda algum cliente se conectar, enquanto a execuo do servidor fica bloqueada na chamada do mtodo accept() da classe ServerSocket (objeto ss). Quando algum cliente se conectar ao servidor, o mtodo efetua o desbloqueio e retorna com um objeto da classe Socket (conexao), que uma porta da comunicao. Linhas 20: A partir da conexo estabelecida, criado um objeto de ServidorBatePapo que implementa Runnable, portanto se comporta como uma Thread.

Aplicativo de Chat

APLICATIVO SERVIDOR
Threads - prof. Gregorio Perez Peiro

15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.

while ( true ){ System.out.print( "Esperando conexao ..." ); Socket conexao = ss.accept(); System.out.println( " Conectado !" ); ServidorBatePapo server1 = new ServidorBatePapo( conexao ); aplicativoServidor.execute( server1 ); } } catch ( IOException ioe ){ System.out.println( "IOException: " + ioe); } } }

23

Linhas 22: Aps ser criado, o servidor executado

Aplicativo de Chat

CLIENTE
Threads - prof. Gregorio Perez Peiro

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

import java.io.IOException; import java.net.Socket; import java.util.Scanner; public class ClienteBatePapo implements Runnable { private static boolean encerrado = false; private Socket conexao; public ClienteBatePapo( Socket soquete ) { conexao = soquete; }

O cliente se comporta, essencialmente, como um servidor, porm est sujeito disponibilidade do servidor em prestar a conexo. Uma varivel lgica criada para avaliar a existncia da conexo e se esta deve ser terminada.

24

continua ...

Aplicativo de Chat

CLIENTE
Threads - prof. Gregorio Perez Peiro

13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.

public void setEncerrado ( boolean fim){ encerrado = fim; } public boolean getEncerrado ( ){ return encerrado; } public void run( ) { try{ Scanner entrada = new Scanner( conexao.getInputStream( ) ); String linha;

25

continua ...

Aplicativo de Chat

CLIENTE
27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42.

while (true) { if ( !entrada.hasNext( ) ) { System.out.println(Conexao Encerrada!); break; } linha = entrada.nextLine( ); System.out.print( \n + linha + \n...> ); } } catch ( IOException ioErro ) { System.out.println( "IOException: " + ioErro ); } setEncerrado( true ); }

Na estrutura de repetio principal (linhas 28 a 35), verificado se a entrada vlida (se houve uma entrada). Se a conexo foi interrompida, no existe uma entrada vlida e o valor da entrada null. Se isso ocorrer, termina-se a execuo saindo com break, caso contrrio o cliente aguarda a prxima entrada vlida.

Threads - prof. Gregorio Perez Peiro

26

Aplicativo de Chat

APLICATIVO CLIENTE
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class AplCliente { public static void main( String [] args ) { try { Socket conexao = new Socket( 127.0.0.1 , 2222 ); PrintStream saida = new PrintStream( conexao.getOutputStream( ) ); continua ...

No aplicativo que executa o cliente deve ser determinado o endereo do servidor e a porta que este servidor disponibiliza para a conexo. Linha 12: o aplicativo cliente procura estabelecer uma conexo com um servidor na porta 2222 do endereo 127.0.0.1 que o servidor local. Se o servidor for remoto, o endereo deste servidor deve ser indicado. Pode-se identificar os endereos disponveis na rede com apoio da classe InetAddress (pacote java.net). Veja exemplo no final desta apresentao.

Threads - prof. Gregorio Perez Peiro

27

Aplicativo de Chat

APLICATIVO CLIENTE
16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.

Na

Scanner teclado = new Scanner( System.in ); System.out.print( Entre com o seu nome: ); String meuNome = teclado.nextLine( ); saida.println( meuNome ); ExecutorService aplicativoCliente = Executors.newFixedThreadPool( 1 ); ClienteBatePapo cliente = new ClienteBatePapo( conexao ); aplicativoCliente.execute( cliente ); String linha;

conexo, o cliente aguarda uma identificao e estabelece uma conexo. Cada cliente necessita apenas uma conexo com o servidor, portanto limitamos a quantidade de threads a uma (linha 23). Naturalmente no seria necessrio definir um conjunto de threads de tamanho 1, poderamos definir o cliente como uma thread (extends Thread), mas mantivemos a estrutura para padronizao.

Threads - prof. Gregorio Perez Peiro

28

continua ...

Aplicativo de Chat

APLICATIVO CLIENTE
Threads - prof. Gregorio Perez Peiro

30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.

while (true) { System.out.print( > ); linha = teclado.nextLine( ); if ( cliente.getEncerrado( ) ) { break; } saida.println( linha ); } conexao.close( ); aplicativoCliente.shutdown( ); } catch ( IOException ioErro ) { System.out.println( "IOException: " + ioErro ); } } }

29

Adendo

RECONHECENDO O LOCAL HOST


1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

import java.net.*; public class MeuEndereco { public static void main (String args[]){ try { InetAddress me = InetAddress.getLocalHost(); String endereco = me.getHostAddress(); System.out.println("Endereco: " + endereco); } catch (UnknownHostException erro){ System.out.println(Nao sei onde estou !\n + erro); } } }

Threads - prof. Gregorio Perez Peiro

30

REFERNCIAS

[01] S.Oaks & H. Wong; Java Threads, 3 ed. (2004) Ed. OReilly

Threads - prof. Gregorio Perez Peiro

[02] H.M.Deitel & P.J.Deitel; Java, Como Programar, 6 ed. (2005) Ed. Pearson - www.deitel.com

[03] A.Silberschatz, P.Galvin & G.Gagne; Sistemas

Operacionais, Conceitos e Aplicaes ; 6 ed. (2001) Ed. Campus

[04] A.Tanenbaum; Sistemas Operacionais Modernos ,

2 ed. (2000) Ed. Pearson - ww.prenhall.com/tanenbaum_br

[05] E.R.Harold; Java Networking Programming, 3 ed. (2004) Ed. OReilly

31

REFERNCIAS

[06] A.Tanenbaum e M.Van Steen; Sistemas Distribudos. Princpios e Paradigmas, 2 ed. (2007) Ed. Pearson

Threads - prof. Gregorio Perez Peiro

[07] G.Coulouris, J.Dollimore, T. Kindberg; Distributed Systems: Concepts and Design, 3 ed. (2001) Addisson-

Wesley www.cdk3.net - www.booksites.net/cdkbook


[08]
http://java.sun.com/docs/books/tutorial/networking/sockets/

32

Вам также может понравиться