Você está na página 1de 6

Tecnologia de Comunicação em Sistemas Distribuídos

Java Socket e Java RMI

Java RMI

O Java RMI é uma interface de invocação remota da linguagem Java, do


inglês Remote Method Invocation que permite que aplicações distribuídas
executem chamadas remotas baseadas na Chamada Remota de Procedimento,
do inglês RPC (acrônimo de Remote Procedure Call) em aplicações
desenvolvidas em Java. Esta interface atua como middleware, que abstrai ao
programador questões envolvendo diferenças em hardware, rede, entre outros
aspectos que poderiam levar preocupações desnecessárias ao programador que
deverá concentrar seu trabalho apenas na questão da programação.
O principal propósito do RMI é o mesmo do RPC: facilitar a programação
de uma aplicação distribuída na medida que esconde do programador a maioria
dos detalhes relacionados com a comunicação em ambiente distribuído. Através
da utilização da arquitetura RMI, é possível que um objeto ativo em uma máquina
virtual Java possa interagir com objetos de outras máquinas virtuais Java,
independentemente da localização dessas máquinas virtuais. Esta API, fornece
ferramentas para que seja possível ao programador desenvolver uma aplicação
sem se preocupar com detalhes de comunicação entre os diversos possíveis
elementos (hosts) de um sistema.
Esta interface se posiciona em uma camada do middleware que fica
abaixo da camada de aplicação e acima das camadas de protocolo de
comunicação; sistema operacional e hardware. O RMI abstrai ao programador
as diferenças encontradas nas camadas inferiores. O programador não terá
muita dificuldade em implementar um sistema com objetos distribuídos, pois o
RMI possui como uma de suas vantagens a facilidade em se programar em
distribuído, pois mantém uma semântica muito semelhante a programação que
envolve objeto locais. A programação só não é idêntica à quando programamos
com objetos locais, pois em sistemas distribuídos há questões de rede envolvida
que vão fazer com que seja necessário o tratamento de exceções e execuções
particulares.
Em resumo, os passos para construir uma aplicação simples que utiliza
RMI são três. Inicialmente é necessário definir uma interface remota que
descreve como o cliente e o servidor se comunicam um com o outro. Em seguida,
é necessário criar o código do programa servidor que implementa a interface
remota definida antes. Finalmente, deve-se criar o programa cliente que,
utilizando uma referência da interface remota, invoca os métodos da
implementação remota da interface definida antes. Obviamente, uma vez
definida a interface remota, os programas cliente e servidor podem ser
desenvolvidos em paralelo.

Vantagens:

 Orientado a objetos
 Quase transparente com relação à chamada local: sintática e
semanticamente;
 Mais legível (vs sockets);
 Atendimento concorrente à vários clientes;
 Uso de máquinas multiprocessadores / multicore;
 Melhor atendimento de chamadas curtas;
 Transferência automática de código (por classes);
 Construção de interfaces usando a própria linguagem Java, sem a
necessidade de uma linguagem separada para a descrição de
interfaces.

Desvantagens:

 Menos flexível (com relação a algoritmos e padrões de comunicação);


 Menos eficiente (versus sockets);
 Somente entre programas Java (deixa a programação restrita à
linguagem Java);
 Síncrono: espera execução do método;
 Modelo de relacionamento cliente/servidor em nível de objetos;
 Simples, único;
 Um (1) servidor para vários clientes;
 Criação (gerência) de servidores pelo servidor.
Java Socket

O socket é uma abstração que representa um ponto de comunicação em


uma rede de computadores. A troca de informações entre máquinas diferentes,
utiliza o conceito de socket, no qual um computador atua como servidor, abrindo
o socket e ficando na escuta, a espera de mensagens ou pedidos de conexões.
O outro computador assume o papel de cliente, enviando mensagens para o
socket do servidor.
Existem dois modos de operação: orientado a conexão, baseado no
protocolo TCP (Transport Control Protocol) e sem conexão, empregando o
protocolo UDP (User Datagram Protocol). Para usar sockets orientados a
conexão, antes do envio dos dados é necessário o estabelecimento de uma
conexão entre o cliente e o servidor. A conexão deve ser terminada ao final da
comunicação e os dados chegam na mesma ordem que foram enviados. Quando
sockets sem conexão são empregados, a entrega não é garantida. Dados podem
chegar em ordem diferente da que foram enviados. O modo usado depende das
necessidades da aplicação. Via de regra, o uso de conexão implica em maior
confiabilidade, porém com maior overhead.
Cada computador em uma rede TCP/IP possui endereço IP único. Portas
representam conexões individuais com esse endereço. Quando o socket é
criado, ele deve ser associado com uma porta específica, isto é, efetuar o seu
binding. Para estabelecer uma conexão o cliente precisa conhecer o endereço
IP da máquina onde o servidor executa e o número da porta que o servidor está
escutando.
A comunicação em si é feita com o auxílio de classes tipo streams, que
são classes do pacote java.io. Os clientes seguem sempre a mesma receita
básica: cria um socket com conexão cliente e utiliza classes que implementam
streams para efetuar a comunicação. Existem diversas opções para sockets
clientes, tais como definir o timeout usado no protocolo de desconexão, timeout
utilizado em operações de leitura, etc.
Um servidor pode receber várias requisições de conexão ao mesmo
tempo e as requisições são processadas uma a uma. A fila de requisições ainda
não atendidas é denominada pilha de escuta. O tamanho da fila de escuta indica
quantas requisições de conexão simultâneas são mantidas. Assim, na
construção acima, o primeiro parâmetro é o número da porta a ser escutada e o
segundo parâmetro é o tamanho da pilha de escuta. O valor default é 50.
O método accept() é chamado para retirar requisições da fila. Ele bloqueia
o processo até a chegada uma requisição, e após isso, retorna um socket
conectado com o cliente. O objeto socket do servidor não é usado, um novo é
criado para a transferência dos dados. O socket do servidor continua enfileirando
pedidos de conexão. Finalmente, streams são usados para a troca de dados. Um
servidor simples processa uma conexão de cada vez.
Entretanto, utilizando múltiplas threads, um servidor concorrente vai criar
uma nova thread para cada conexão aberta e assim consegue processar várias
conexões simultaneamente. Por exemplo, servidores web comerciais são todos
concorrentes.
No caso de comunicação baseada em datagramas, a classe
DatagramSocket é usada tanto por clientes como por servidores. O servidor deve
especificar sua porta, e a omissão do parâmetro significa “use a próxima porta
livre”. O cliente sempre utiliza a próxima.
A classe DatagramPacket é usada para enviar e receber dados. Ela
contém informações para conexão e os próprios dados. Para receber dados de
um socket datagrama, o método receive() bloqueia até a recepção dos dados.
O envio de uma string para um socket destinatário é feito através da montagem
de um objeto DatagramPacket, o qual conterá a mensagem e o endereço
destino. Seu envio através do método send() de objeto da classe
DatagramSocket criado anteriormente pelo cliente.

Vantagens:

 Mais eficiente;
 Mais flexível (com relação a algoritmos e padrões de comunicação);
 Aprendizado rápido;
 API uniforme (sobre outras API sockets).

Desvantagens:

 Menos legível;
 Não orientado a objetos em termos de chamada, mas usa classes e
objetos.

Principais diferenças entre os modelos Java RMI e Java Socket

 Sockets basicamente transmitem dados em baixo nível entre programas


remotos. Dessa forma, se o programa existente realiza a comunicação a
partir de sockets, não importa em que idioma ele está escrito, desde que
os formatos das mensagens correspondam. O Java RMI possui um nível
alto, no qual permite que você execute um método de um programa
remoto, aguardando o retorno como se fosse uma chamada de método
local, no entanto, esta opção é realmente apenas para comunicação entre
programas Java;

 O Java RMI é uma API que serve para você fazer chamadas de métodos
remotas. Por exemplo, você consegue executar um método em outro
computador. Socket seria um ponto de conexão entre dois computadores,
o IP e porta de um computador através de especificações TCP ou UDP;

 O Java RMI é um protocolo usado pelo Java para comunicação entre


processos (programas) diferentes.Socket é um ponto de comunicação
entre processos através de uma rede de computadores, um conceito de
baixo nível.

Definição de Modelo Cliente/Servidor

Interações em um sistema distribuído ocorrem, usualmente, através do


modelo cliente-servidor. No modelo cliente-servidor, um sistema é estruturado
em processos cooperantes que assumem papeis de clientes ou de servidores.
Um processo assume o papel de servidor quando ele oferece serviços aos outros
processos clientes. Um mesmo processo pode ora fazer papel de cliente, ora
papel de servidor. Por exemplo, um processo servidor de nomes, pode receber
uma requisição para resolução de um nome o qual ele não possa resolver. Nesse
caso, o servidor, temporariamente, assume papel de cliente fazendo uma
requisição para outro servidor de nomes. Servidores de tempo (NTP) também
funcionam de forma hierárquica, onde alguns servidores sincronizam seus
relógios, periodicamente, fazendo requisições a outros servidores.
A maneira mais simples de implementar um modelo cliente-servidor é
através de um protocolo simples do tipo requisição/resposta (request/reply).
Essas primitivas, por sua vez, podem ser implementadas através de operações
de envio e recepção de mensagens existentes, por exemplo, na API
socket.Nessa implementação de protocolo, um processo cliente, envia uma
mensagem de requisição para um servidor requisitando algum serviço
(fazOperação()). Essa operação bloqueia o processo cliente enquanto não é
retornada uma mensagem de resposta. No outro ponto final da comunicação, o
servidor já estava bloqueado aguardando alguma requisição de serviço
(aguardaPedido()). Ao receber o pedido de requisição, o servidor se
desbloqueia, extrai a mensagem, executa a operação pedida pelo cliente, e
retorna uma mensagem para o cliente (enviaResposta()). Um exemplo
tradicional de implementação de um protocolo requisição/resposta é o HTTP,
usado em interações entre navegadores e servidor web.

Referência Bibliográfica

ftp://ftp.inf.ufrgs.br/pub/geyer/PDP-CIC-
ECP/slidesAlunos/SemestresAnteriores/ProvaP1-2013-1/j07-javaComunicacao-
v4d1-mar2013.pdf
Acesso em: 28 set. 2017.

http://www.romulosilvadeoliveira.eng.br/artigos/Romulo-Joni-Montez-
Eri2002.pdf
Acesso em: 28 set. 2017.

Você também pode gostar