Baixe o app para aproveitar ainda mais
Prévia do material em texto
SISTEMAS DISTRIBUÍDOSSISTEMAS DISTRIBUÍDOS COMUNICAÇÃO ENTRE COMUNICAÇÃO ENTRE PROCESSOSPROCESSOS Autor: Dr. Sidartha Azevedo R e v i s o r : L i z a n d r o d e S o u z a I N I C I A R introdução Introdução Caro(a) aluno(a), nesta unidade você vai aprender o que são os sockets e como eles são utilizados na comunicação entre processos. Você vai aprender algumas primitivas dos soquetes (do inglês, sockets), como o send() e o receive(). Além disso, você vai ver exemplos práticos com o uso dos sockets, utilizando a linguagem de programação Java. Ademais, para possibilitar a comunicação correta entre os processos, é necessário entender os mecanismos de garantia do sincronismo entre as máquinas, visto que elas se comunicam por uma rede de dados. Por fim, você vai entender o que é uma chamada remota de procedimento e como esse conceito é importante nos sistemas distribuídos. Caro(a) aluno(a), antes de falarmos dos sockets, é importante relembrar alguns conceitos importantes sobre os protocolos de comunicação. Os protocolos de comunicação definem estratégias que devem ser seguidas para garantir o bom funcionamento e alcance dos benefícios oferecidos pela implementação do protocolo. A seguir, iremos falar sobre os dois principais protocolos: Transmission Control Protocol (TCP) e User Datagram Protocol (UDP) (COULOURIS, DOLLIMORE; KINDBERG, 2013). O protocolo TCP é utilizado em conjunto com o Internet Protocol (IP), sendo nomeado geralmente como TCP/IP. Esse protocolo é responsável por levar a mensagem do emissor até o receptor e garantir que a mensagem foi entregue de forma total. Os sistemas webs utilizam esse protocolo quando é necessário enviar dados onde não se pode ter falta desses dados, em que a corretude é mais importante do que a velocidade de entrega. O protocolo TCP/IP pode dividir o dado a ser enviado (se for muito grande) em pequenos pacotes, que são enviados de forma individual e organizados no destino para formar a mensagem original. O TCP/IP garante que todos esses pequenos pacotes irão chegar ao receptor e então serão combinados na ordem correta. SocketsSockets Diversos tipos de sistemas utilizam o TCP/IP, por exemplo: acesso aos sites na Internet, uso do e-mail, acesso ao aplicativo do banco, transferência de arquivos, dentre outros. Por possuir o benefício da entrega correta dos pacotes enviados e da garantia de que todos os pacotes serão entregues, esse protocolo pode sofrer alguns atrasos. Por exemplo, se um pacote for perdido durante o seu envio, é necessário esperar até que seja verificado que ele foi perdido e então o cliente envia uma mensagem ao servidor avisando que não recebeu determinado pacote. Logo após, o servidor reenvia somente aquele dado perdido e espera a confirmação de recebimento pelo cliente (COULOURIS; DOLLIMORE; KINDBERG, 2013). Ainda de acordo com Coulouris, Dollimore e Kindberg (2013), o protocolo UDP também é utilizado em conjunto com o IP. Esse protocolo caracteriza-se principalmente por não ser orientado à conexão, ou seja, não há um vínculo forte entre o emissor e o receptor. Vamos entender melhor com o exemplo a seguir. Imagine que queremos enviar uma mensagem que está dividida em cinco pacotes. Essa divisão é necessária por restrições da rede, em que há um tamanho máximo do pacote, e, se a mensagem ultrapassar esse limite, deve ser quebrada em pedaços menores para obedecer ao critério. Usando o protocolo UDP, os cinco pacotes são enviados de forma sequencial, sem a garantia de que serão entregues ou se chegarão ao destino na ordem correta. Pode ocorrer de haver um erro na rede ou que um determinado pacote utilize outro caminho para chegar até o destino, podendo ser o primeiro a ser enviado, mas o último a chegar no destino. Esse protocolo é ágil, pois não utiliza tempo com o reenvio de pacotes ou espera da confirmação do destinatário dizendo que recebeu o pacote (utilizado no TCP). As principais diferenças entre o protocolo TCP e o UDP estão ilustradas no quadro a seguir. Quadro 2.1 - Comparativo entre TCP e UDP Fonte: Adaptado de Coulouris, Dollimore e Kindberg (2013) e Tanenbaum (2007). Um dos principais usos do protocolo UDP é o streaming de vídeos na Internet, em que a rapidez de chegada é mais importante do que a confiabilidade no envio. Por exemplo, em cada segundo de vídeo temos aproximadamente 30 imagens, e, se uma dessas imagens se perder, a falha pode não ser perceptível ao olho humano que está assistindo ao vídeo. No entanto, se o vídeo parar e esperar que o pacote com aquela imagem chegue, é mais prejudicial do que descartar essa imagem/pacote faltante. A seguir, vamos entender alguns conceitos importantes sobre os sockets e as primitivas de comunicação. Definição e Primitivas A interface sockets é utilizada para permitir a comunicação entre os sistemas dentro da rede. Para realizar a comunicação, podemos implementar as interfaces sockets em diversas linguagens, mas, para os nossos exemplos, iremos utilizar a linguagem Java por motivos de facilidade de entendimento. Primeiro, precisamos ter um servidor Java que irá responder as requisições dos clientes. Após isso, vamos implementar o lado do cliente, que irá enviar requisições ao servidor e aguardar a resposta. Para haver comunicação entre os processos, também chamada de comunicação interprocessos, faz-se necessário o uso de um mecanismo de transporte das informações, possibilitando que o cliente acesse dados, recursos ou serviços em um servidor remoto. O mecanismo mais utilizado é o socket, o qual é a maneira mais eficaz de usar as funcionalidades dos protocolos de comunicação TCP/IP. Lembre-se de que os mecanismos dos sockets são gerenciados na camada de transporte. Para usar os conceitos de sockets, pode-se usar interfaces de programação, por exemplo o WinSock para o Windows ou a interface sockets do Unix. Durante a comunicação, o socket é o ponto final da comunicação, por exemplo, se um cliente deseja se comunicar com um servidor, o ponto inicial no cliente será o socket do cliente e o ponto final do lado do servidor será o socket do servidor. Cada socket possui endereço local e endereço global, sendo: o endereço local é o número da porta que permite o tráfego de dados na camada de transporte dentro da máquina local; e o endereço global é o nome da máquina que armazena o socket, por exemplo o endereço IP ou localhost. Para identificar uma conexão entre dois pontos, usamos a tupla <IP,PORTA>. Imagine que um cliente de IP = 192.168.0.100 quer se comunicar com o servidor de IP 10.5.6.88. O cliente precisa enviar uma mensagem ao sistema operacional utilizando a API WinSock do Windows para ter acesso a uma porta do sistema operacional: AbrirSocket(888), em que 888 é a porta local do socket. Para iniciar a comunicação com o servidor, o cliente deve enviar uma requisição contendo o IP e a porta do servidor: <10.5.6.88;566>, em que 566 é a porta no servidor. Para receber a requisição, é necessário que o servidor esteja esperando uma conexão, ou seja, esteja ouvindo a rede naquela porta especifica (a 566). A API Socket (ORACLE, 2020, on-line) possui alguns métodos padrões. Vamos entendê-los a seguir. • Bind ○ Associa o número da porta a um socket. ○ Função utilizada apenas pelo servidor, uma vez que associa um determinado endereço IP e porta TCP ou UDP para o processo servidor. ○ Exemplo: bind(socket, localaddr, addrlen) ■ socket: socket associado para ser registrado. ■ localaddr: endereço local para vincular o socket. ■ addrlen: valor inteiro que determina o tamanho do endereço em bytes. • Listen: ○ Indica ao sistema operacional para colocar o socket em modo de espera (passivo) para aguardar conexões de clientes. ○ Exemplo: listen(socket, queue) ■ socket: socket que ficará em modo passivo aguardando por conexões. ■ queue: tamanho máximo da fila de conexões que serão aceitas pelo socket. • Accept:○Cria um novo socket a partir do estabelecimento de uma conexão para iniciar a comunicação (leitura e escrita). ○ Exemplo: newsock = accept(socket, addr, addrlen) • Read: ○ Lê o conteúdo do buffer associado ao socket. ○ Exemplo: read(socket, buffer, length) • Write: ○ Escreve dados em um buffer associado ao socket. ○ Exemplo: write(socket, buffer, length) • Close: ○ Informa ao sistema operacional para fechar um socket. ○ Exemplo: close(socket) • Chamada gethostbyname(endereço): ○ Extrai o endereço IP a partir do nome de um servidor. • Chamada getprotobyname(protocolo): ○ Extrai o código correspondente ao protocolo a partir de uma string. A seguir, você vai aprender um pouco mais com exemplos aplicados em sistemas do cotidiano e usando o modelo cliente-servidor. Exemplos com Cliente e Servidor Aluno(a), veremos que a figura a seguir ilustra uma comunicação entre dois elementos, um cliente e um servidor. O cliente, localizado no lado esquerdo da figura, possui o endereço IP = 138.37.94.248, enquanto o servidor, no canto direito da figura, possui o endereço IP = 138.37.88.249. Note que tanto o cliente quanto o servidor possuem um socket, o qual é responsável por encaminhar as mensagens (também chamados de pacotes) para a porta reservada para a comunicação (note que tanto o cliente quanto o servidor possuem diversas portas). Em resumo, o processo que executa dentro da máquina cliente é responsável por realizar o processamento, preparar a mensagem e encaminhar pelo socket até a porta reservada; após isso, a mensagem é enviada pela rede (podendo usar diversos meios físicos como Internet sem fio ou cabeada) e, ao chegar na porta do servidor, é encaminhada para o socket responsável por aquela porta que está associada a outro processo que executa dentro do servidor reservado para tratar aquela requisição. praticarVamos Praticar Os sockets possibilitam um canal de comunicação entre computadores, permitindo que um processo associado a uma máquina localizada em uma rede possa se comunicar com outro processo localizado em outra máquina em uma rede diferente. De acordo com os conceitos sobre os sockets, qual a principal responsabilidade da primitiva bind()? a) Indica ao sistema operacional para colocar o socket em modo de espera (passivo) para aguardar conexões de clientes. b) Cria um novo socket a partir do estabelecimento de uma conexão para iniciar a comunicação (leitura e escrita). c) Lê o conteúdo do buffer associado ao socket. d) Associa o número da porta a um socket. e) Escreve dados em um buffer associado ao socket. Aluno(a), agora que vimos a importância, utilidade e algumas primitivas do uso dos sockets, vamos entender melhor como é a implementação de um sistema distribuído que utiliza sockets para se comunicar. Nos exemplos a seguir, iremos utilizar a linguagem Java, uma das mais lembradas na construção da comunicação por sockets para os sistemas distribuídos. Implementação Utilizando Sockets Para fazer uso dos sockets TCP/IP, é necessário importar as seguintes bibliotecas na classe Java (ORACLE, 2020, on-line): • import java.io.IOException; • import java.io.PrintWriter; • import java.net.ServerSocket; • import java.net.Socket. A classe do lado do servidor pode ser definida como o exemplo a seguir: SocketsSockets No exemplo acima, note que primeiro criamos um objeto do tipo ServerSocket e especificamos a porta na qual esse processo vai se comunicar dentro do sistema operacional. Utilizamos a porta 60000. Após isso, exibimos uma mensagem no console da IDE de programação para avisar que o servidor está em execução. Lembre-se de que o servidor se mantém em execução de forma infinita, como vimos anteriormente. Utilizamos um laço while infinito para possibilitar o servidor estar sempre atento para o recebimento de novas requisições do cliente. Ao chamar o método ouvinte.accept(), o nosso sistema estará bloqueado até que uma nova requisição seja recebida, ou seja, não haverá execução das linhas de código seguinte enquanto não tivermos uma requisição (chamamos de método bloqueante). Quando um cliente enviar uma requisição ao servidor, será utilizado o método socket.getOutputStream() para receber o fluxo de dados que foi enviado pelo cliente, estabelecendo o canal de comunicação e possibilitando a troca de dados. Por fim, escrevemos no canal de comunicação a mensagem que será enviada de volta ao cliente com o comando saida.println(), onde saída é o nosso objeto proveniente do ouvinte.accept(). A seguir, está um exemplo da classe que deve executar no computador do cliente que irá se comunicar com o servidor especificado logo acima. Note que especificamos o IP como sendo: 127.0.0.1. Esse IP corresponde à máquina local onde está executando. No nosso exemplo, servidor e cliente estão executando na mesma máquina. Ao utilizar a rede aberta, é só trocar o IP pelo número correto. Lembre-se de que a porta utilizada tanto no servidor quanto no cliente deve ser a mesma; caso contrário, não haverá comunicação. A variável do tipo scanner contém os métodos necessários para a leitura dos dados no canal de comunicação criado pelo socket, utilizando o TCP/IP. O exemplo acima é bem simples, pois o nosso servidor somente consegue atender um cliente por vez, o que é inviável em sistemas comerciais. Para estender o exemplo acima, iremos modificar a classe Servidor para atender a vários clientes de forma simultânea com o uso de threads do Java. Observe o código Java a seguir: Na função main do nosso servidor, definimos que o número máximo de clientes aceitos de forma simultânea será de 100 clientes. Após isso, o servidor fica executando de forma indefinida, esperando requisições dos clientes. Ao chegar uma requisição, uma nova thread é criada e o trabalho que será feito é redirecionado para outra thread. Esse procedimento permite que o servidor não fique bloqueado enquanto não terminar de responder ao primeiro cliente. Dentro da ThreadDespachante, são criadas variáveis para enviar e receber dados (entrada e saída). Sempre que houver alguma mensagem a ser recebida, ela é processada e enviada para a saída do canal, usando a variável saída. Ao final da ThreadDespachante, é preciso fechar a comunicação que foi aberta para poder liberar os recursos que estão sendo utilizados para manter o canal de comunicação com o cliente. Se esse procedimento de socket.close() não for realizado, chegará um momento em que não será mais possível receber pedidos, pois todos os recursos do servidor estarão ocupados com canais ociosos, sem uso. praticarVamos Praticar A sincronização é um problema recorrente aos sistemas distribuídos, alvo de diversas pesquisas em todo o mundo. Dado esse problema da não sincronização nos sistemas distribuídos, é necessário que haja ações para que se garanta a possibilidade de comunicação entre os computadores da rede mesmo em situações adversas. Para que o servidor possa receber uma requisição de um cliente, é necessário que: a) Utilize o modelo cliente-servidor. b) Use a API sockets para Windows. c) Use threads masters em cada requisição. d) Implemente um loop infinito para poder receber a requisição que vai chegar do cliente. e) Use a arquitetura peer-to-peer para possibilitar o uso da API sockets. Estudante, antes de falarmos da sincronização em sistemas distribuídos, é necessário entender melhor os conceitos relacionados a seguir. Os relógios físicos nos computadores são usados para sincronizar a comunicação entre os componentes e utilizam um cristal que oscila a uma frequência constante sob certa tensão. Cada conjunto de ciclos é convertido para software e atualiza o relógio relativo da máquina. Essas marcações estão suscetíveis a atrasos com o passar do tempo, sendo necessário haver ajustes de tempos em tempos. Quando se realiza a comunicação em sistemas distribuídos, cada sistema individual possui seu relógio e o utilizapara marcar a troca de mensagens. A partir do momento em que não utilizam o mesmo tempo para se comunicarem, há problemas de sincronismo. Um exemplo de problema é a compilação por meio do comando MAKE no sistema operacional Linux: o comando MAKE lê todos os arquivos fontes (.c) e os arquivos objetos (.o). Se o arquivo (.o) for mais velho que o arquivo (.c), não será preciso recompilar o código (TANENBAUM, 2007). Veja o exemplo: uma máquina compila o arquivo fonte localmente no tempo 2144; após isso, uma outra máquina, com um tempo diferente, faz uma alteração no arquivo fonte e registra a alteração com tempo 2143. Ao executar o comando MAKE, Sincronização e Sincronização e Coordenação em Sistemas Coordenação em Sistemas DistribuídosDistribuídos ele verá que o arquivo objeto é mais velho que o fonte, logo, já foi compilado e não precisará ser feito novamente, o que é um erro grave. Uma forma de sincronizar os relógios é fazendo uso do Universal Coordinated Time (UTC) em todas as máquinas do sistema distribuído. Uma abordagem é que todas as máquinas da rede devem consultar um servidor único, chamado de servidor de tempo que possui acesso ao WWV (uma estação que informa o tempo de forma precisa). Porém, o tempo do atraso da comunicação acaba fazendo com que o tempo consultado já esteja desatualizado quando retornado ao servidor de tempo. Além disso, o problema é agravado se houver deslocamentos de tempo. As máquinas não precisam conhecer exatamente o tempo “correto”, desde que utilizem a mesma sequência cronológica. Outra abordagem é fazer o uso de estratos, em que algumas máquinas possuem seus relógios atualizados e as máquinas com estratos mais baixos devem atualizar seus relógios de acordo com as máquinas de estrato mais alto. Nessa abordagem, deve-se atentar ao problema de nunca atrasar os relógios, sempre os adiantando para não gerar alguns dos problemas vistos anteriormente. A seguir, você vai entender mais sobre alguns algoritmos que auxiliam na garantia de sincronismos entre as máquinas nos sistemas distribuídos. Definição e Exemplos Algoritmo de Berkeley: na ausência de WWV, um daemon periodicamente consulta as máquinas, faz a média dos tempos e sugere que a máquina adiante ou atrase seus relógios. Não é essencial que esteja com a hora real exata, mas que trabalhe com o mesmo tempo. Sincronização em redes sem fio: esse tipo de estrutura sofre com grandes atrasos na comunicação e alto consumo de energia, por conta da comunicação. Nessa abordagem, não há nós sensores que são usados como servidores de tempo, e o tempo real não é tão importante, mas a sincronização é essencial. Além disso, a sincronização em broadcast por referência é feita através de nós que enviam seus tempos em broadcast, calculam as distâncias entre os nós, estimam o valor do tempo gasto na comunicação e atualizam o relógio. Relógios lógicos: nesse tipo de abordagem, o tempo real não é crucial. São criados relógios lógicos que garantem a ordem correta das execuções, embora não possuam a hora real. Uma das principais abordagens de relógios lógicos é a proposta por Lamport. Algoritmo de Lamport: é mais importante a ordem dos eventos do que a sincronização com o tempo real. Os sistemas devem apresentar uma concordância nas ordens das execuções, embora não possuam atualização do tempo real. Lamport definiu que os sistemas devem concordar na ordem de execução das operações, se a → b, “a” acontece antes de “b” e b → c, então a → c. O algoritmo corrige o tempo da mensagem e aumenta em 1 ciclo de clock quando essa mensagem chega ao destinatário que tem um tempo anterior ao da mensagem. Exemplo: P1, P2 e P3 são máquinas que possuem seus relógios distintos. Segundo as regras de transição de Lamport, se uma mensagem sai de P3 com tempo 60 e chega no P2, onde esse tem tempo 48, não é aceitável. O tempo deve ser maior que 60, então o algoritmo ajusta o relógio de P2 de acordo com o tempo de P3+1. praticarVamos Praticar Os sistemas distribuídos se comunicam através da rede de dados e, muitas vezes, não se conhecem. Para prover uma comunicação correta, é necessário que eles utilizem protocolos bem definidos (geralmente públicos) e que possuam mecanismos de sincronização de dados e de protocolos. Em relação à sincronização em sistemas distribuídos, assinale a alternativa correta. a) Os sistemas distribuídos devem utilizar sempre o tempo exato em relação aos homens. b) Os sistemas distribuídos devem utilizar sockets para sincronizar os tempos. c) O tempo nos relógios dos sistemas distribuídos são definidos na fabricação dos componentes. d) Os relógios dos sistemas distribuídos devem compartilhar o mesmo tempo. e) Deve-se utilizar um servidor WWV para roteador as mensagens pelos sockets. Nesta seção, você vai aprender sobre as chamadas remotas de procedimento. De forma resumida, é o procedimento de invocar um método de forma remota, ou seja, um cliente chama um método em um servidor usando a rede. Porém, lembre-se de que a chamada remota de procedimentos não se restringe ao uso da arquitetura cliente-servidor. Definição e Exemplos Antes de falarmos de invocação remota, vamos relembrar como acontece uma invocação de método de forma local, em um programa qualquer. Na chamada de procedimento convencional, há a passagem por valor ou referência da variável. Veja um exemplo da invocação do método read(): read(fd, buf, nbytes), onde fd é um inteiro que indica um arquivo, buf é o vetor onde os dados são lidos e o nbytes informa quantos bytes devem ser lidos. A ideia da chamada remota de procedimento é fazer com que uma chamada remota seja o mais perto possível de uma chamada local. Ou seja, deve-se abstrair a informação de chamada remota para o invocador do método. Em um sistema local, a Chamada Remota de Chamada Remota de Procedimento (RPC)Procedimento (RPC) chamada read() pede que o sistema operacional lhe forneça dados. Já na chamada remota, o read() é substituído por uma extensão da função, que, ao invés de pedir os dados ao sistema operacional, pede que envie a mensagem empacotada pela função, usando a rede. Dando continuidade, geralmente após fazer uso do método read() se usa o método receive(), que é bloqueante. O método receive() é usado para captar os dados que estão sendo enviados para um determinado processo. As chamadas são convertidas em chamadas locais no servidor e tudo é transparente, tanto para o cliente quanto para o servidor. A versão modificada do read() é chamada de apêndice de cliente e apêndice de servidor. Veja um exemplo a seguir. A figura anterior ilustra um exemplo de uma chamada remota a partir de um cliente para um servidor. Primeiro, o processo cliente está fazendo algum processamento e necessita requisitar uma funcionalidade (método) presente em um servidor, localizado fisicamente distante do requisitante. Dentro do código do cliente, há abstrações para que o programador não perceba que está invocando um método remoto, sendo a chamada remota similar a uma chamada de um método local. Após isso, um pacote é enviado pela rede com a requisição para o servidor. Esse recebe e processa a mensagem, executa o procedimento desejado pelo cliente e então retorna a resposta (saída do método) para o cliente, finalizando a interação. Em complemento, chamada remota de procedimento é uma forma genérica de descrever a troca de mensagens entre processos em sistemas distribuídos. Arquitetura A arquitetura de uma chamada remota de procedimento define como deve ocorrer a comunicação e define os principais elementos que compõem essa chamada. A figura a seguir ilustra uma arquitetura geral para a chamada remota de procedimentos. A chamada remota de procedimentos geralmente segue a sequência a seguir: 1. A aplicação cliente necessita de alguma informação/processamento a ser realizada fora da máquina local. 2. A necessidade é convertida emuma requisição que é empacotada em uma mensagem que vai ser transferida pela rede. 3. A mensagem é enviada pela rede e transportada até o destino. 4. A camada de transporte no servidor é responsável por receber a mensagem e encaminhar para o processo adequado, referenciado pelo <IP e porta>. 5. A mensagem é traduzida para entidades locais do servidor (por exemplo, classes Java). 6. A mensagem é entregue ao processo responsável por realizar a requisição. 7. A resposta do servidor passa pelas etapas de conversão, empacotamento e envio pela rede. 8. A resposta é recebida pelo servidor, convertida e entregue ao processo cliente. praticarVamos Praticar A chamada remota de procedimentos é uma atividade comum no desenvolvimento e uso de sistemas distribuídos. A chamada remota permite que processos locais acessem funcionalidades ou dados em máquinas diferentes, geralmente usando uma rede de dados, como a Internet. Sobre as chamadas remotas de procedimento, assinale a alternativa correta. a) A chamada remota de procedimento sempre irá retornar a resposta que o cliente deseja. b) A arquitetura de chamada remota de procedimentos sempre é baseada na arquitetura cliente-servidor. c) Não há distinção entre a arquitetura cliente-servidor e chamada remota de procedimentos. d) A chamada remota de procedimento sempre irá retornar uma resposta. e) O envio da requisição remota deve usar o protocolo UDP. indicações Material Complementar L I V R O Sistemas distribuídos: conceitos e projeto George Coulouris, Jean Dollimore e Tim Kindberg Editora: Bookman ISBN: 0321263545 Comentário: No material indicado, você vai aprender sobre o algoritmo de Lamport, o qual descreve como deve ser feita a comunicação entre dois sistemas distribuídos para permitir o sincronismo correto entre as partes comunicantes. Mais informações podem ser consultadas na p. 608 do livro de Coulouris, Dollimore e Kindberg. F I L M E Blade Runner (The Final Cut) Ano: 2007 Comentário: Esse filme vai lhe ajudar a entender a complexidade que existe em manter a comunicação entre diversos sistemas em tempo real, sendo essa dificuldade comum aos sistemas distribuídos. Além disso, você vai perceber como era a tecnologia concebida anos atrás e a que temos hoje, as semelhanças e diferenças. T R A I L E R conclusão Conclusão Nesta unidade, você analisou os conceitos básicos sobre os sockets e aprendeu que há duas primitivas principais: o send() e o receive(), usados para enviar e receber dados, permitindo que processos distintos se comuniquem utilizando uma rede de dados. Também foi visto um exemplo de código em Java ilustrando a comunicação entre dois processos: um cliente e um servidor, usando sockets. E como um servidor pode tratar diversas requisições de diferentes clientes usando threads. Além disso, entendemos como funciona o sincronismo de relógios nos sistemas distribuídos, necessário para a comunicação. Por fim, foi exemplificado o que é uma chamada remota de procedimento e como ela pode ser usada de forma transparente para os programadores em sistemas distribuídos. referências Referências Bibliográficas BLADE RUNNER (The Final Cut) (Legendado). 2017. 1 vídeo (117 min.). Disponível em: https://www.youtube.com/watch?v=pgqcLyZeA8U. Acesso em: 22 jan. 2020. COULOURIS, G.; DOLLIMORE, J.; KINDBERG, T. Sistemas distribuídos: conceitos e projeto [recurso eletrônico, Minha Biblioteca]. São Paulo, Bookman, 2013. IANA. Service Name and Transport Protocol Port Number Registry, 17 jan. 2020. Disponível em: https://www.iana.org/assignments/service-names-port- numbers/service-names-port-numbers.xhtml. Acesso em: 21 jan. 2020. MICROSOFT. How RPC Works, 30 maio 2018. Disponível em: https://docs.microsoft.com/en-us/windows/win32/rpc/how-rpc-works. Acesso em: 21 jan. 2020. NIST. Radio Station WWV, 15 nov. 2019. Disponível em: https://www.nist.gov/pml/time-and-frequency-division/radio-stations/wwv. Acesso em: 21 jan. 2020. OPENJDK. Local variables, 2018. Disponível em: https://openjdk.java.net/projects/amber/LVTIFAQ.html. Acesso em: 21 jan. 2020. ORACLE. Java: Class Socket. Disponível em: https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html. Acesso em: 21 jan. 2020. TANENBAUM, A. S. Sistemas distribuídos: princípios e práticas [recurso eletrônico, Biblioteca Virtual]. São Paulo: Pearson Prentice Hall, 2007.
Compartilhar