Sistemas Distribuídos (Parte 4 - Aplicação Distribuída)



Documentos relacionados
Sistemas de Operação Sockets

Comunicação entre Processos

Engenharia Elétrica Eletrônica Slides 20: TCP/IP em Winsocks 2. API do Windows para programar utilizando o protocolo TCP/IP Prof. Jean Marcelo SIMÃO

Programação de Sockets em C/C++

Camada de Transporte, protocolos TCP e UDP

Redes de Computadores II

No projeto das primeiras redes de computadores, o hardware foi a principal preocupação e o software ficou em segundo plano.

Diagrama lógico da rede da empresa Fácil Credito

Disciplina de Redes de Computadores Estudo Dirigido para a Prova II Professor Dr Windson Viana de Carvalho

BACHARELADO EM SISTEMAS DE INFORMAÇÃO EaD UAB/UFSCar Sistemas de Informação - prof. Dr. Hélio Crestana Guardia

Sockets. Bruno Guimarães Lucas Rossini

IMPLEMENTAÇÃO DE SOCKETS E THREADS NO DESENVOLVIMENTO DE SISTEMAS CLIENTE / SERVIDOR: UM ESTUDO EM VB.NET

REDES DE COMPUTADORES

Sistemas Operacionais. Prof. André Y. Kusumoto

Prof. Marcelo Cunha Parte 5

Capítulo II Modelos de Programação Distribuída

Sistemas Distribuídos (DCC/UFRJ)

Sistemas Distribuídos Processos I. Prof. MSc. Hugo Souza

Topologia de rede Ligação Ponto-a-Ponto

SISTEMAS DISTRIBUIDOS

CONCEITOS BÁSICOS DE UM SISTEMA OPERATIVO

Aula Prática. Comunicação em SOCKTS. Disciplina: INF01151

REDE DE COMPUTADORES

Aula 03-04: Modelos de Sistemas Distribuídos

Arquitetura e Protocolos de Rede TCP/IP. Modelo Arquitetural

Redes e Conectividade

1 Redes de Computadores - TCP/IP Luiz Arthur

Programação com Sockets TCP e UDP - Cliente. Gustavo Leitão

TROCA DE MENSAGENS SOCKETS. Comunicando processos através de SOCKETS. SOCKETS com conexão. SOCKETS sem conexão

REDES DE COMPUTADORES

Conceito de Rede e seus Elementos. Prof. Marciano dos Santos Dionizio

Redes de Computadores. Arquitetura de Protocolos Profa. Priscila Solís Barreto

Programação com sockets (em Java)

ORGANIZAÇÃO DE COMPUTADORES MÓDULO 1

Exercícios de Revisão Redes de Computadores Edgard Jamhour. Nome dos Alunos

REDES COMPONENTES DE UMA REDE

USO GERAL DOS PROTOCOLOS SMTP, FTP, TCP, UDP E IP

Redes de computadores. Redes para Internet

2 Gerenciamento de Log 2.1 Definições básicas

Redes de Computadores. Prof. André Y. Kusumoto

Redes. Pablo Rodriguez de Almeida Gross

Introdução a Banco de Dados Aula 03. Prof. Silvestri

Considerações no Projeto de Sistemas Cliente/Servidor

Até o final de década de 70, os sistemas operacionais suportavam apenas processos com um único thread;

06/10/2015. Modelo TCP/IP Camada de Transporte DISCIPLINA: TECNOLOGIA DE REDES DE COMPUTADORES. UDP User Datagram Protocol. UDP User Datagram Protocol

Relatório do Laboratório 3

Redes de Computadores Camada de Aplicação. Prof. MSc. Hugo Souza

Aula 4. Pilha de Protocolos TCP/IP:

Arquitetura de Rede de Computadores

Evolução na comunicação. Organização de uma viagem aérea. Camadas de Protocolos. Camadas de Funcionalidade da companhia aérea. Por que as Camadas?

MÓDULO 7 Modelo OSI. 7.1 Serviços Versus Protocolos

Um Tutorial sobre Sockets Parte I

Introdução à Computação: Sistemas de Computação

UMA ABORDAGEM SOBRE A INTERFACE DE PROGRAMAÇÃO DE APLICAÇÕES SOCKETS E A IMPLEMENTAÇÃO DE UM SERVIDOR HTTP

Comunicando através da rede

Sistemas Distribuídos Capítulos 3 e 4 - Aula 4

1. O DHCP Dynamic Host Configuration Protocol

REDES DE COMPUTADORES - I UNI-ANHANGUERA CENTRO UNIVERSITÁRIO DE GOIÁS CURSO DE ANÁLISE E DESENVOLVIMENTO DE SISTEMAS PROF.

REDES DE COMPUTADORES Prof. Ricardo Rodrigues Barcelar

Firewall IPTables e Exemplo de Implementação no Ambiente Corporativo.

Rede de Computadores

Disciplina: Redes de Comunicação. Curso Profissional Técnico de Gestão e Programação de Sistemas Informáticos. Setembro 2013

1. Explicando Roteamento um exemplo prático. Através da análise de uns exemplos simples será possível compreender como o roteamento funciona.

TRANSMISSÃO DE DADOS Prof. Ricardo Rodrigues Barcelar

Redes de Computadores. 1 Questões de múltipla escolha. TE090 - Prof. Pedroso. 17 de junho de 2015

Módulo de Transmissão e Ativos de Rede Curso Técnico de Informática. Prof. George Silva

Capítulo 8 - Aplicações em Redes

Redes de Computadores (RCOMP 2014/2015)

Redes de Computadores. 1 Questões de múltipla escolha. TE090 - Prof. Pedroso. 30 de novembro de Exercício 1: Considere:

Interconexão de Redes. Aula 03 - Roteamento IP. Prof. Esp. Camilo Brotas Ribeiro cribeiro@catolica-es.edu.br

Capítulo 7 CAMADA DE TRANSPORTE

4 Implementação e Ambiente de Simulação

Unidade IV GERENCIAMENTO DE SISTEMAS. Prof. Roberto Marcello

FTIN Formação Técnica em Informática Módulo de Administração de Servidores de Rede AULA 02. Prof. Gabriel Silva

Curso: Redes II (Heterogênea e Convergente)

Resolução de Problemas de Rede. Disciplina: Suporte Remoto Prof. Etelvira Leite

MINISTÉRIO DA EDUCAÇÃO

Rede d s d e d Com o pu p t u ado d r o es Conceitos Básicos M d o e d los o de d Re R de d s:

Sistemas Distribuídos

Arquitetura de Rede de Computadores

sockets interprocess communication Taisy Weber

Equipamentos de rede. Repetidores. Repetidores. Prof. Leandro Pykosz

Bibliotecas. Apoio à Programação Distribuída. Socket. Socket. bibliotecas bibliotecas+ferramentas linguagens de programação distribuídas

Capítulo 9 - Conjunto de Protocolos TCP/IP e Endereçamento. Associação dos Instrutores NetAcademy - Julho de Página

Redes de Computadores. Protocolo TCP/IP Profa. Priscila Solís Barreto

Sumário INTRODUÇÃO... 4 PROTOCOLO ARP...5 ARP - ADDRESS RESOLUTION PROTOCOL...5 FUNCIONAMENTO DO PROTOCOLO ARP...5 CACHE ARP... 6

2 Ferramentas Utilizadas

Banco de Dados Orientado a Objetos

SISTEMAS OPERACIONAIS

Rede de Computadores (REC)

Sistemas Distribuídos

Permitir a troca de mensagens de texto entre os dois alunos; Permitir que um aluno enviasse para o outro uma cópia de prova;

Redes de Computadores e a Internet

Aula-16 Interconexão de Redes IP (Internet Protocol) Prof. Dr. S. Motoyama

Informática I. Aula Aula 22-03/07/06 1

APLICAÇÃO REDE APLICAÇÃO APRESENTAÇÃO SESSÃO TRANSPORTE REDE LINK DE DADOS FÍSICA 1/5 PROTOCOLOS DE REDE

ADDRESS RESOLUTION PROTOCOL. Thiago de Almeida Correia

DALUA: BIBLIOTECA PARA APLICAÇÕES DISTRIBUÍDAS

Transcrição:

Unidade de Gestão da Educação Presencial - GEDUP Pós-graduação em Redes de Computadores Sistemas Distribuídos (Parte 4 - Aplicação Distribuída) Prof. Ms. Tomás Dias Sant Ana Varginha, 2006

Sumário 1. INTRODUÇÃO...1 2. APLICAÇÃO DISTRIBUÍDA...2 2.1 COMPUTAÇÃO DISTRIBUÍDA...2 3. TÉCNICAS PARA IMPLEMENTAÇÃO DE APLICAÇÕES DISTRIBUÍDAS...5 3.1 ARQUITETURA CLIENTE/SERVIDOR...5 3.1.1 O protocolo TCP-IP...7 3.1.2 O endereço IP...8 3.1.3 Portas...8 3.2 Sockets...9 3.2.1 Criação de um socket...10 3.2.2 Stream Socket...11 3.2.2 Datagrama Socket...14 3.4 Programação Multi-Threading...16 8. BIBLIOGRAFIA...20

1 1. Introdução Até pouco tempo, na construção das aplicações monolíticas que rodam nos mainframes, o projetista tinha pouca ou quase nenhuma preocupação com a arquitetura da aplicação. Com a viabilização da rede e das tecnologias de comunicação e processamento distribuído, determinar a arquitetura de uma aplicação passou a ser uma atividade estratégica na construção de sistemas e inclui decidir sobre o seu particionamento e a localização de suas partes. O crescimento das redes de computadores e meios de comunicação, bem como a heterogeneidade das plataformas de hardware e software impulsionou a investigação científica de aspectos como abertura, transparência, mobilidade do usuário, confiabilidade, interoperabilidade e outros, todos inerentes aos sistemas distribuídos (Tanenbaun, 1996; Coulouris et al., 1994). Em adição, o advento da Internet, em termos de uma grande rede mundial que engloba plataformas de hardware e software bastante heterogêneas, impulsionou ainda mais o desenvolvimento dos sistemas distribuídos, embora nem todos os conceitos essenciais de sistemas distribuídos estejam presentes na Internet. Fornecido o suporte à conexão das máquinas e também o suporte operacional, é relevante investigar os recursos providos pelas linguagens de programação e/ou ambientes de desenvolvimento, em termos da implementação de aplicações distribuídas. Existem várias linguagens que fornecem suporte ao desenvolvimento de aplicações, geralmente através de bibliotecas que contemplam recursos para o estabelecimento de conexões entre computadores, transferência de mensagens, controle dos aspectos envolvidos na comunicação e outros. A heterogeneidade das plataformas de hardware e software é um ponto positivo para o uso de sistemas distribuídos, visto que a integração dos diferentes ambientes operacionais é um dos focos de investigação científica da área. No entanto, ao nível dos desenvolvedores de aplicações (programadores), o desenvolvimento de aplicações que possam ser executadas em diferentes ambientes operacionais é um grande desafio, pois a maioria das linguagens de programação está ligada diretamente a um determinado tipo de sistema operacional.

2 2. Aplicação Distribuída Aplicações distribuídas são aquelas em que existem programas que executam simultaneamente em vários computadores interligados em rede. Para que os diferentes programas, que constituem a aplicação distribuída, possam comunicar entre si precisam obedecer a regras, designadas por protocolos. A complexidade da especificação desses protocolos e mesmo a necessidade de reutilização de software fizeram com que esses protocolos fossem estruturados em famílias de protocolos, com uma determinada arquitetura. Uma família de protocolos, também designada por pilha de protocolos, caracteriza-se por uma arquitetura e pelo fato dos seus protocolos serem aprovados por uma mesma entidade. Desde o inicio, os vários fabricantes se lançaram a definir as suas famílias de protocolos: SNA (IBM), DNA (Digital), etc. Mas, cedo se constatou um problema: como executar aplicações distribuídas em ambientes heterogêneos? É naturalmente de todo interesse que estes tipos de aplicações possam ser usados em ambientes heterogêneos, isto é, ambientes onde coexistam computadores de fabricantes diferentes, com sistemas operacionais diferentes. Para que isso seja possível, precisam existir famílias de protocolos normalizadas internacionalmente, independentemente dos fabricantes. Existem duas famílias de protocolos com esse estatuto: a família de protocolos OSI, normalizada conjuntamente pela ISO e pelo CCITT; os protocolos desta família são divulgadas por normas ISO e recomendações do CCITT; a família de protocolos Internet (TCP/IP, descrito no item 3.1.2), normalizada pelo IAB (Internet Activities Board); os protocolos desta família são divulgados como RFC's (Request For Comments). 2.1 Computação Distribuída

3 A computação distribuída divide a carga de processamento entre dois ou mais computadores. No entanto, as coisas não são tão simples. Hoje temos que olhar além dos conceitos tradicionais de computação distribuída, partindo do mundo two-tier (i. e. clienteservidor) para um mundo mais complexo, onde aplicações são divididas entre múltiplos processadores e bancos de dados. Ainda mais, estas aplicações precisam manter as suas características de missão crítica tais como tolerância à falhas e recuperação de erros. Para entender a integração de aplicações multitiered (múltiplos pontos), precisamos entender a arquitetura. O particionamento de aplicações é realmente um conceito de arquitetura, onde a tecnologia (por exemplo, objetos distribuídos) é um mero mecanismo para implementação de uma aplicação particionada. Uma decisão fundamental para a construção de um sistema distribuído é a arquitetura base a ser utilizada. Uma vez selecionada a arquitetura base, o projetista precisa decidir onde colocar os processos da aplicação para melhor otimizar os recursos disponíveis e atender os requisitos da aplicação. Há muitas coisas a serem consideradas, incluindo: carga do usuário; carga do processamento; tipo da aplicação; custo de desenvolvimento; manutenção; expectativas de desempenho. Como se cria uma arquitetura? Antes de se optar por uma arquitetura, algumas atividades precisam ser executadas como entender os requisitos em detalhes, criar o projeto da aplicação e considerar todos os itens acima mencionados. Um dos erros mais comuns que os arquitetos cometem é abordar o problema com uma arquitetura pré-definida e tentar fazer o problema se ajustar a ela. Não é uma boa idéia. O mais recomendável é selecionar a arquitetura que melhor se ajuste ao problema em mãos. O primeiro passo é criar uma arquitetura lógica. Uma arquitetura lógica permite o mapeamento de certas funções da aplicação em camadas da arquitetura conceitual, sem comprometimento com uma determinada camada ou tecnologia disponível. Assim como no

4 projeto lógico de banco de dados, é recomendável entender os objetivos e metas da arquitetura antes de entrar nos seus detalhes. Agora que se tem uma arquitetura lógica, é hora de concentrar as atenções para o mapeamento do lógico para o físico. Antes é necessário selecionar as tecnologias de apoio como sockets, ferramentas de particionamento de aplicações, ferramentas especializadas de computação distribuída, servidores de banco de dados ou objetos distribuídos. A tecnologia de apoio definirá como os objetos lógicos serão fisicamente implementados.

5 3. Técnicas para Implementação de Aplicações Distribuídas Os Sistemas Distribuídos podem ser caracterizados como sendo um conjunto de computadores autônomos, interligados por uma rede de comunicação, e que permitem o compartilhamento dos recursos do sistema, tais como hardware, software e dados. Em adição, o acesso aos recursos oferecidos por um sistema distribuído deve ser transparente aos olhos do usuário, ou seja, independente de sua localização, o usuário deve acessar os serviços da mesma forma, tendo a impressão de que o sistema é o seu computador. Atualmente a maioria dos sistemas distribuídos baseia-se na arquitetura clienteservidor e no uso do protocolo TCP-IP. 3.1 Arquitetura Cliente/Servidor A organização dos sistemas distribuídos deve considerar os aspectos lógicos, tais como estrutura lógica do sistema, relação usuário/sistema, conceito de clientes-servidores e outros; e os aspectos físicos, tais como estrutura física, organização do hardware, elementos básicos e outros. De modo geral, os modelos arquiteturais dos sistemas distribuídos podem ser classificados em clássicos, compostos e avançados. Os modelos arquiteturais clássicos compreendem o modelo de minicomputadores, o modelo estação de trabalho-servidor e modelo de banco de processadores. Atualmente, o modelo clássico baseado em estações de trabalho-servidor, conforme ilustra a Figura 3.1, tem sido o mais difundido por apresentar uma arquitetura simplificada e flexível, que se adapta às necessidades da maioria dos usuários.

6 Estações de Trabalho e Computadores Pessoais Rede de Comunicação Roteador (ligação com uma WAN) Servidores de Arquivos Outros Servidores Figura 3.1 Modelo arquitetural estação de trabalho-servidor O modelo estação de trabalho-servidor é caracterizado pela presença de um ou mais servidores e várias estações de trabalho (clientes). O servidor é responsável pelo gerenciamento e disponibilização dos recursos às estações de trabalho que, por sua vez, realizam os pedidos. De modo geral, o processo de comunicação do cliente e servidor envolve um meio de transmissão e um protocolo de comunicação, por exemplo UDP (User Datagram Protocol) ou TCP (Transfer Control Protocol). O TCP é um protocolo baseado em conexão que prove um fluxo de dados confiável entre dois computadores, exemplos: HTTP, FTP, Telnet. E UDP é um protocolo que envia pacotes de dados independentes, chamados datagramas, de um computador para o outro, exemplo: Ping. Utilizando o protocolo TCP, o servidor possui um módulo de software que permanece sempre em execução (listening) para atender às chamadas dos clientes. Uma conexão é criada com o servidor sempre que um cliente solicita algum serviço. Em adição, o servidor é capaz de manter várias conexões com os clientes simultaneamente, conforme ilustra a Figura 3.2. Os pedidos dos clientes chegam ao servidor em um endereço lógico, denominado porta, que identifica o tipo de serviço a ser realizado. Após o recebimento da solicitação, o

servidor executa o serviço, "empacota" o resultado e envia de volta ao cliente, utilizando o mesmo endereço lógico. 7 Cliente 1 Servidor Cliente 2 Cliente 3 Figura 3.2 - Esquema genérico de uma conexão cliente-servidor 3.1.1 O protocolo TCP-IP Atualmente, a Internet apresenta-se como o mais difundido modelo de comunicação cliente-servidor. Através dela é possível interligar redes do mundo inteiro, utilizando-se para isto um protocolo de comunicação padrão, denominado TCP/IP (Transfer Control Protocol - Internet Protocol), e computadores intermediários, chamados routers ou gateways, que são responsáveis pela troca (comutação) de pacotes entre as redes (Commer, 1991; Thomas, 1997). De modo geral, cada rede possui um endereço IP, utilizado para identificá-la dentre as demais redes da Internet. Em adição, cada placa de rede de um computador possui um endereço único determinado pelo fabricante, que é utilizado para a localização do computador dentro de uma rede. Assim, ao enviar um pacote de um computador a outro via Internet, deve-se acrescentar um endereço lógico, que inclui o endereço da rede e o endereço do computador. Os routers utilizam o processo de ARP (Address Resolution Protocol) para localizar o computador de destino. Este processo consiste em receber o pacote, verificar se o endereço lógico faz parte da lista de endereços de rede que ele possui, enviar um broadcast a todos os computadores da rede e, após a identificação do endereço físico, enviar o pacote ao computador.

8 3.1.2 O endereço IP Conforme citado, o endereço IP é um endereço lógico utilizado para a localização de um computador em uma rede TCP/IP. Basicamente, o endereço IP é um número de 32 bits composto por quatro conjuntos de oito bits (quatro bytes), como por exemplo 10110001 00101111 00010110 101110100, que podem ser traduzidos para os conjuntos numéricos 136.47.238.169 (Thomas, 1997). Para facilitar a tarefa de roteamento, os endereços IP são hierárquicos. Desta forma, ao receber um pacote, o router pode identificar se este é ou não para a sua rede. Como exemplo, se uma rede possui o endereço IP 135.10.0.0, todos os seus computadores devem possuir endereço do tipo 135.10.x.x. Com o objetivo de facilitar a localização de um servidor (host), o endereço IP é traduzido para um nome, por exemplo "unifenas.br". O processo inverso, ou seja, a tradução do nome para o endereço IP é denominada Hostname Resolution (resolução de nomes). O sistema de roteamento verifica a existência de um nome em tabelas de DNS (Domain Name System) mantidas pelos diversos mecanismos roteadores (routers), através dos endereços IP (Internet Protocol). Caso o servidor seja encontrado e esteja em operação, uma interface é fornecida ao usuário para acesso aos serviços disponíveis. 3.1.3 Portas Conforme citado, a comunicação pela Internet não é simplesmente a comunicação entre dois computadores, mas sim entre duas aplicações. Para que isto seja possível, a mensagem enviada pela aplicação cliente deve conter uma identificação da aplicação servidora, neste caso, o endereço lógico denominado porta. Em adição, a aplicação cliente deve enviar o número da porta para recebimento da resposta. Todas estas informações são adicionadas ao header do pacote. O endereço lógico deve possuir um número de 16 bits na faixa entre 0 (zero) e 65535, sendo que as portas de número inferior a 1024 (entre 0 e 1023) são reservadas para aplicações padrões, por exemplo HTTP, que utiliza a porta 80; FTP, a porta 21; Telnet, a porta 23; e outras (figura 3.3).

9 Figura 3.3 - Esquematização das Portas 3.2 Sockets Sockets são os componentes básicos para comunicação entre processos, prove acesso ao protocolo de transporte de rede. Os dois principais tipos de sockets são: Stream Socket: um stream socket prove uma comunicação bidirecional, confiável, seqüencial e não duplicada. Utiliza o protocolo TCP/IP. Datagram Socket: prove a comunicação bidirecional de dados, o dado é dividido em pacotes, as mensagens podem ser recebidas fora de ordem e ou duplicadas. Ele usa o protocolo UDP. O estabelecimento da conexão é assimétrico, com um processo atuando como cliente e outro como servidor: O servidor estabelece (bind) um socket para um endereço conhecido. Ele bloqueia o socket para um pedido de conexão. O processo pode conectar com o servidor.

10 3.2.1 Criação de um socket O primeiro passo é criar o socket, através da função socket(): s = socket(domínio, tipo, protocolo) onde, Domínio: é especificado por uma das constantes definidas em <sys/socket.h>. Para o UNIX o domínio é AF_UNIX e para a Internet o domínio é AF_INET. Tipo: são suportados três tipos de sockets: SOCK_STREAM para stream sockets, SOCK_DATAGRAM para datagram sockets e SOCK_RAW para Row Sockets.Protocolo: O argumento 0 deve ser usado na maioria dos casos. O sistema seleciona um protocolo que suporta o tipo de requisição. O socket é criado sem um nome, mas deve-se especificar o nome para que a comunicação possa ocorrer entre as aplicações. A função bind() permite o processo especificar um meio de comunicação: bind (s, nome, tamanho_do_nome) S: é o handle do socket. Nome: é uma estrutura que é interpretada por um protocolo. Exemplo: o domínio Internet contém um Internet Address e o número da porta. Tamanho do Nome: é o tamanho da estrutura nome Exemplo Internet biding: int sock; struct sockaddr_in Nome; Nome.sin_family = AF_INET; Nome.sin_addr.s_addr = INADDR_ANY; Nome.sin_port = 0; bind (sock, (struct sockaddr *)&Nome, sizeof(nome)); Solicitação (ouvindo) e Communicating (comunicando) Pedido canal: servidor apenas escuta o pedido. Canal de comunicação: é criado para cada comunicação.

11 Figura 3.4 - Representação da comunicação utilizando Strem Socket 3.2.2 Stream Socket Lado do Cliente No lado cliente a função connect() inicia uma conexão, e automaticamente seleciona um nome (bind) para o socket: int Sock; struct sockaddr_in Servidor; struct hostent *hp;... Servidor.sin_family= AF_INET; hp= gethostbyname("host name"); memcpy((char*) & Servidor.sin_addr, (char*) hp->h_addr, hp->h_length); Servidor.sin_port= htons(port_number);... connect(sock, (struct sockaddr*) &Servidor, sizeof(servidor)); A função gethostbyname(nome_host) retorna uma estrutura incluíndo o endereço de rede do Host (NOME_HOST). Lado do Servidor Para receber uma conexão cliente, o servidor deve realizar os seguintes passos após o binding (Figura 3.4): 1. Indicar quantas conexões podem ser colocadas em fila (listen()). 2. Aceitar a conexão (accept()). int Sock; struct sockaddr_in Cliente;... listen(s, 5);... Sock = accept(sock, (struct sockaddr *)&Cliente, sizeof(cliente)); Listen(S, 5) S é o endereço do socket para conexão, e o segundo parâmetro especifica o número máximo de conexões que podem ser colocadas em fila. Accept() retorna um novo socket que é conectado ao cliente.

Transferência de dados: Há várias funções para enviar e receber dados. A função socket() retorna um descritor de arquivo que pode ser usado com muitas chamadas I/O do UNIX, por exemplo: write(sock, mensagem, sizeof(buf)); read(sock, mensagem, sizeof(buf)); ou, send(sock, mensagem, sizeof(buf), flag); recv(sock, mensagem, sizeof(buf), flag); 12 Fechando um socket: O socket deve ser fechado usando a função close(). Exemplo: close(s). Exemplo Cliente: #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <strings.h> #define DATA "1 2 3 TESTANDO..." main (int argc, char* argv[]) { int sock; struct sockaddr_in server; struct hostent *hp; sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == -1) { perror ("Opening stream socket"); exit (1); hp = gethostbyname(argv[1]); memcpy ((char*)&server.sin_addr, (char*) hp->h_addr, hp->h_length); server.sin_family = AF_INET; server.sin_port = htons(atoi(argv[2])); if (connect(sock, (struct sockaddr *)&server, sizeof server) == -1) { perror("connecting stream socket"); exit(1); if (write(sock, DATA, sizeof DATA) == -1) perror("writing data to stream socket"); close (sock); exit (0);

13 Exemplo Servidor: #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <strings.h> #define TRUE 1 main() { int sock, length; struct sockaddr_in server; int msgsock; char buf[1024]; int rval; sock = socket (AF_INET, SOCK_STREAM, 0); if (sock==-1) { perror( "Opening stream socket"); exit(1); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = 0; if (bind (sock, (struct sockaddr *)&server, sizeof(server)) == -1){ perror("binding stream socket"); exit (1); length = sizeof server; if (getsockname (sock, (struct sockaddr *)&server, &length) == -1){ perror("getting socket name"); exit (1); printf("socket port # %d\n", ntohs(server.sin_port)); /* Start accepting connections */ listen(sock, 5); do { msgsock = accept( sock, (struct sockaddr *) 0, (int*) 0); if (msgsock==-1) perror("accept"); else do { memset( buf, 0, sizeof buf); if (( rval = read( msgsock, buf, 1024)) == -1) perror("reading data stream"); if (rval == 0) printf("ending connection\n"); else printf( "-->%s\n", buf); while (rval!=0); close(msgsock); while (TRUE); exit(0);

14 3.2.2 Datagrama Socket Um datagram socket é criado como um stream socket, alterando apenas o flag que define o tipo do socket. Ele pode usar algumas chamadas para enviar e receber dados como no stream socket, exceto as funções accept() e listen(). As funções sendto() e recvfrom() são muito usadas para transferir dados em um datagram socket: sendto(s, buf, sizeof(buf), flag, &to, sizeof(to)); Envia o conteúdo de buf para o endereço indicado em &to. recvfrom(s, buf, sizeof(buf), flag, &from, sizeof(from)); Recebe o pacote e armazena em buf. Exemplo Cliente: #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <strings.h> #define DATA "Mensagem..." main (int argc, char* argv[]) { int sock; struct sockaddr_in server; struct hostent *hp; char buf[1024]; sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock == -1) { perror ("Opening stream socket"); exit (1); hp = gethostbyname(argv[1]); memcpy ((char*)&server.sin_addr, (char*) hp->h_addr, hp->h_length); server.sin_family = AF_INET; server.sin_port = htons(atoi(argv[2])); if (sendto(sock, DATA, sizeof DATA, 0, (struct sockaddr *)&server, sizeof server) == -1) { perror("enviando dados"); exit(1); if (read(sock, buf, 1024) == - 1) perror("writing data to stream socket"); printf("teste: %s\n", buf); close (sock); exit (0);

15 Exemplo Servidor: #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <strings.h> #define TRUE 1 main() { int sock, length; struct sockaddr_in server; struct sockaddr_in cliente; int msgsock; char buf[1024]; int rval; sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock==-1) { perror( "Opening stream socket"); exit(1); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = 0; if (bind (sock, (struct sockaddr *)&server, sizeof(server)) == -1){ perror("binding stream socket"); exit (1); length = sizeof server; if (getsockname (sock, (struct sockaddr *)&server, &length) == -1){ perror("getting socket name"); exit (1); printf("socket port # %d\n", ntohs(server.sin_port)); do { if (recvfrom (sock, buf, 1024, 0, (struct sockaddr *)&cliente, &length) == -1) { perror ("Lendo pacote"); exit(1); if (sendto (sock, buf, 1024, 0, (struct sockaddr *)&cliente, sizeof cliente) == -1) { perror ("enviando pacote"); exit(0); printf("mensagem %s\n", buf); while (TRUE); exit(0);

16 3.4 Programação Multi-Threading No princípio da computação paralela, os termos concorrência e multiprogramação possuíam conceitos completamente distintos e eram aplicados a situações também distintas. Com a evolução do hardware e das técnicas de programação, tais termos passaram a ser complementares e, atualmente, são utilizados em conjunto para se construir técnicas híbridas para a computação paralela. Na programação seqüencial, os processos são executados um após o outro, enquanto que na programação concorrente os processos são executados concorrentemente. A Concorrência implica em mais de um processo iniciado e ainda não terminado, podendo ocorrer tanto em sistemas com um único processador (pseudoparalelismo multiprogramação), como em sistemas com vários processadores (programação paralela). Dentro desta definição, pode-se abstrair dois tipos de paralelismo: Pseudo-Paralelismo (Threads): os processos são executados de forma intercalada em um único processador, de maneira que apenas um está ativo a cada instante. A Figura 2.1 exemplifica este tipo de paralelismo, com a execução de três processos (e1, e2 e e3) em função do tempo. Processos e3 e3 e2 e2 e1 e1 t1 t Tempo Figura 3.1 Pseudo-Paralelismo Paralelismo Real: vários processos são executados no mesmo intervalo de tempo, ou seja, têm-se vários processadores podendo executar os processos simultaneamente (Figura 2.2). Se existem p processos e P processadores sendo executados concorrentemente, e p > P, forma-se uma situação de paralelismo misto.

17 Processos e3 e1 e2 Figura 3.2 Paralelismo Real O paralelismo real pode ser dividido em três tipos: paralelismo espacial (paralelismo real), temporal (pipeline) e combinado. t1 t Tempo O paralelismo espacial está relacionado à execução simultânea dos processos. O paralelismo temporal, ou pipeline, implica na execução de eventos sobrepostos no tempo. O processo é dividido em vários subprocessos, sendo cada um executado em um estágio especializado de hardware e software operando concorrentemente com os outros estágios do pipeline [HWA93] [NAV89]. Estágios Figura 3.3 Execução de um Pipeline A Figura 2.3 demonstra o funcionamento de um pipeline de quatro estágios (E1, E2, E3 e E4). Os estágios são organizados seqüencialmente de maneira que o primeiro estágio (E1) executa uma parte do processo P1 e, ao terminar, entrega o resultado para o segundo estágio que dará continuidade ao processamento. A cada unidade de tempo, um novo processo é iniciado, denominados P1, P2, P3..., Pn. Após quatro unidades de tempo, neste exemplo, o fluxo de processos completos torna-se contínuo, sendo que um processo é executado a cada unidade de tempo (paralelismo de eventos sobrepostos). No paralelismo combinado existem vários estágios de pipeline sendo executados em paralelo. E4 E3 E2 E1 P1 P2 P1 P2 P3 P1 P2 P3 P4......... P1 P2 P3 P4 P5... t1 t2 t3 t4 t5... t Tempo

18 Multiprogramação baseada em threads A multitarefa é a capacidade de se ter mais de um programa executando aparentemente ao mesmo tempo, podendo acontecer de duas maneiras, dependendo da capacidade de controle de tarefas do sistema operacional. Num primeiro caso, quando o sistema operacional sempre insiste na continuidade de um programa, a multitarefa é dita preemptiva. Por outro lado, quando o sistema operacional opta para que o programa coopere com outros programas, a multitarefa é dita cooperativa. A programação multiple threads estende ainda mais a idéia de multitarefa, fazendo com que dentro de um mesmo programa existam várias tarefas executando ao mesmo tempo. Neste contexto, cada fluxo de controle dentro de um programa é denominado thread. Desta forma, quando um programa possuir mais de uma unidade computacional é denominado multithreading. Um thread pode estar em cinco estados diferentes: Executando (Runnable): o thread está sendo executado. Ativo (Active): o thread está pronto para ser executado. Dormindo (Sleeping): o thread está dormindo, após sua execução. Stopped (Parado): o thread está parado esperando por algum recurso. Zombie (Zumbi): o thread foi finalizado. O exemplo abaixo implementa a aplicação socket (apresentada no capítulo anterior) utilizando multithreading.

19 pthread_t Servico;... listen(sock, 5); do { NovoSocket = accept(sock, (struct sockaddr *) 0, (int*) 0); if (NovoSocket==-1) perror("accept"); else { if (pthread_create(&servico, NULL, Servicos, NovoSocket)) printf("erro: Criando Thread\n"); pthread_join(servico, 0); while (1==1); close(sock); void* Servicos(void* Sock) { int TamanhoEnd, N; char Mensagem[1024]; char* Retorno; do { memset(mensagem, 0, sizeof Mensagem); if ((N = read(sock, Mensagem, 1024)) == -1) perror("lendo Dados"); if (N!= 0) printf("servchat>%s", Mensagem); ///Parser Retorno="TESTE"; if (send(sock, Retorno, strlen(retorno)+1, 0) == -1) perror("enviando Dados"); while (N!=0);... Sincronização As técnicas que garantem a comunicação e o acesso a recursos compartilhados são conhecidas como mecanismos de sincronização. A área de dados compartilhados pelos threads é conhecida como região crítica. Os mecanismos de sincronização devem evitar a concorrência nas regiões críticas, permitindo que somente um processo tenha acesso em um determinado instante. Esta idéia de exclusividade de acesso é denominada exclusão mútua. Em sistemas com memória compartilhada existem vários mecanismos para garantir a exclusão mútua, entre eles: mutex, semáforos e monitores. O exemplo abaixo apresenta o programa do produtor/consumidor utilizando threads mutex.

20 Pthread_mutex_t ContaMutex; int Contador;... IncrementaCotnador() { pthread_mutex_lock(&contamutex); Contador = Contador+1; pthread_mutex_unlock(&contamutex); int PegaContador() { int Aux; pthread_mutex_lock(&contamutex); Contador = Contador 1; Aux = Contador; pthread_mutex_unlock(&contamutex); return (Aux) 8. Bibliografia (Commer, 1991) Commer, D. E.: INTERNTEWORKING WITH TCP-IP - PRINCIPLES, PROTOCOLS E ARCHITECTURE. v.3, 1991. (Coulouris et al., 1994) Coulouris, G., Dollimore, J., Kindberg, T.: DISTRIBUTED SYSTEMS - CONCEPTS AND DESIGN. 2 nd ed., Addison- Wesley Publishing Company, 1994. (Huges, 1996) HUGES, Merlin - JAVA, Network Programming, Manning,1996 (Tanenbaun, 1996) (Thomas, 1997) Tanenbaun, A.: DISTRIBUTED OPERATING SYSTEMS. Prentice Hall, 1996. Thomas, M. D. et al.: PROGRAMANDO EM JAVA PARA A INTERNET. Editora Makron Books, São Paulo, 1997.