Sockets em Ruby. Curso de Tecnologia em Redes de Computadores Programação para Redes

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

Sockets. Introdução. Introdução. Programando para redes em Java. mecanismo de alto nível para acessar recursos na Internet.

Comunicação entre processos

Sockets. Bruno Guimarães Lucas Rossini

Comunicação entre Processos

Comunicação em Sistemas Distribuídos. Conceitos: Paradigma C/S. Conceitos: Paradigma C/S. Paradigma Cliente/Servidor

Comunicação Inter-Processos. Prof. Adriano Fiorese. Conceitos Iniciais

Tipos de Servidores. Servidores com estado

Camada de Transporte, protocolos TCP e UDP

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

Programação de sockets com TCP

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

FTP FILE F TRANSFER PROTOCOL. Tópicos

REDES DE COMPUTADORES

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

Java 2 Standard Edition Fundamentos de

Olho por olho, e o mundo acabará cego. Mohandas Gandhi

UNIVERSIDADE ESTADUAL DO OESTE DO PARANÁ CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS COLEGIADO DE INFORMÁTICA

UNIVERSIDADE. Sistemas Distribuídos

Relatório 1º Laboratório: O Java e os Sockets. Licenciatura: ETI Turma : ETC1 Grupo : rd3_t3_02 Data: 22/02/2010

Mecanismos de Comunicação. Sockets em java (

Cliente-servidor com Sockets TCP

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira

Cliente-servidor com Sockets TCP

SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010)

Permite o acesso remoto a um computador;

Programação de Sockets

socket Objetivo: aprender a construir aplicações cliente/servidor que se comunicam usando sockets

Programação: Sockets em Java

Sistemas Distribuídos

Segundo Trabalho de Programação em Ambientes Limitados

Redes de Computadores II

Exercícios de Revisão Java Básico

Redes de Computadores e a Internet

Sistemas Distribuídos

Tópicos em Sistemas Distribuídos. Modelos de Comunicação

INF1013 MODELAGEM DE SOFTWARE

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

Usando o Conference Manager do Microsoft Outlook

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

Java NET: Interaja com a Internet. Ricardo Terra (rterrabh [at] gmail.com) Java NET: Interaja com a Internet Maio,

Programação em Rede Baseada em Java. Luiz Affonso Guedes Tópicos em Redes de Computadores Programação Distribuída

- Aulas 57, 58, 59 e 60 - Técnicas de programação. Funções

DIRETORIA DE TECNOLOGIA DA INFORMAÇÃO SETOR DE ESTÚDIO E SUPORTE MANUAL DE UTILIZAÇÃO DO WEBMAIL DA FTC EAD

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

Redes de Computadores (RCOMP 2014/2015)

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

Programação com sockets (em Java)

Sockets em Java. Leonardo R. Nunes - leonardo@sumersoft.com. 1. Introdução. 2. Sockets TCP/IP

TRABALHO DE REDES DE COMPUTADORES 1 GNUTELLA

Transporte. Sua função é: Promover uma transferência de dados confiável e econômica entre máquina de origem e máquina de destino.

Portal de Aprendizado Tutorial do Aluno

Introdução à Camada de Aplicação. Prof. Eduardo

Endereços de transporte TPDU. Nível de Rede Endereço de rede. Figura 1. Entidade de transporte

Instruções para uma impressora conectada localmente no Windows

Traceroute É uma ferramenta de diagnóstico que rastreia a rota de um pacote através de uma rede de computadores e que utiliza os protocolos IP e ICMP.

Manual do Desenvolvedor Criptografia de Arquivos do WebTA

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

Seu manual do usuário SONY ERICSSON W890I

FTP - Protocolo. O protocolo FTP é o serviço padrão da Internet para a transferência de arquivos entre computadores.


Lab 4 Análise de Pacotes utilizando o TCPDUMP

Camada de Aplicação. Prof. Eduardo

Implementando comunicação em JAVA via Sockets. Alcides Calsavara - alcides@ppgia.pucpr.br Leonardo R. Nunes - leonardo@sumersoft.

Redes de Computadores

Sistemas de Operação Sockets

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

Programa de Computador que funciona em Rede

DALUA: BIBLIOTECA PARA APLICAÇÕES DISTRIBUÍDAS

Aula 30 - Sockets em Java

Fiery Driver Configurator

Sockets com Java Parte I

CAMADA DE TRANSPORTE

Aleph. Entre Bibliotecas. Reunião da REJE 09 de novembro de 2011

PHP (PHP Hypertext Preprocessor)

MINISTÉRIO DA EDUCAÇÃO

CONCEITOS BÁSICOS PARA A CONSTRUÇÃO DE ALGORITMOS PARA COMPUTADORES. Isac Aguiar isacaguiar.com.br isacaguiar@gmail.com

Manual do Desktop Sharing. Brad Hards Tradução: Marcus Gama

Especificação do Trabalho Prático

Arquitetura de Sistemas Operativos

Programação de Sistemas

Programação de Sistemas


Instituto Superior Técnico MEEC/MEAR. Programação de Sistemas

Descrição. Implementação. Departamento de Informática e Estatística Universidade Federal de Santa Catarina LAB 4 Transferência de Arquivos

Exemplos práticos do uso de RMI em sistemas distribuídos


Este documento consiste em 9 páginas. Elaborado por: Innova Tecnologia de Soluções. Liberado em Julho de 2009.

FTP: protocolo de transferência de arquivos

Trabalho de Conclusão de Curso

Endereçamento Privado Proxy e NAT. 2008, Edgard Jamhour

ECD1200 Equipamento de Consulta de Dados KIT DE DESENVOLVIMENTO

Programação Paralela e Distribuída. Prof. Cidcley T. de Souza

Capítulo 2. VARIÁVEIS DO TIPO INTEIRO

CARTOSOFT GUIA PRÁTICO PROCART SISTEMAS

Manual do Usuário do Produto EmiteNF-e. Manual do Usuário

Guia do Aplicativo Bomgar B200 Índice

Transcrição:

Sockets em Ruby Curso de Tecnologia em Redes de Computadores Programação para Redes

Sockets em Ruby A biblioteca padrão de Ruby oferece um conjunto de classes para a manipulação de sockets. require socket Para aplicações baseadas em TCP: Classes TCPServer e TCPSocket. Para aplicações baseadas em UDP: Classe UDPSocket. 2

Classe TCPSocket Representa um socket baseado em TCP. É utilizado pelo cliente e pelo servidor para a troca de mensagens. Construtor new(host, porta) Cria e retorna um novo TCPSocket capaz de enviar dados para um servidor TCP localizado em host (nome ou endereço IP). Utilizado pelo cliente para conectar-se a um servidor. Método close() Fecha o socket, não sendo mais possível a E/S de dados. A entrada e saída de dados pode ser realizados pelos métodos de saída normalmente utilizados com streams (puts, print, write, syswrite, gets e read) ou pelos métodos específicos a sockets (recv, recfrom e send). 3

Classe TCPServer Classe TCPServer: representa um socket servidor baseado em TCP. Construtor new(porta) Cria e retorna um novo socket TCPServer na porta especificada. Método accept() Coloca o socket em modo de espera. A execução fica bloqueada até que seja recebida uma requisição cliente. Retorna uma instância de TCPSocket que é utilizada para receber e enviar dados para o cliente. 4

Exemplo: servidor calculadora (1/2) require 'socket' def processar(linha) tokens = linha.split if tokens[0] == 'soma' return tokens[1].to_f + tokens[2].to_f elsif tokens[0] == 'raiz_quadrada' return Math.sqrt(tokens[1].to_f) else return 'Mensagem invalida' end end 5

Exemplo: servidor calculadora (2/2) serversocket = TCPServer.new(2000) puts 'Servidor calculadora iniciado' loop { } clientsocket = serversocket.accept while linha = clientsocket.gets end resposta = processar(linha) clientsocket.puts(resposta) clientsocket.close 6

Exemplo: cliente calculadora require 'socket' hostname = 'localhost' port = 2000 socket = TCPSocket.new(hostname, port) socket.puts('soma 5 3') puts socket.gets socket.puts('raiz_quadrada 100') puts socket.gets socket.puts('maluco 5 3') puts socket.gets socket.close 7

Exemplo: protocolo Na mesma conexão, o cliente pode solicitar várias operações de cálculo. Cada operação deve ser enviada como uma string finalizada com o caractere de nova linha (\n). O primeiro token da linha indica a operação (soma ou raiz quadrada). Os tokens seguintes indicam os argumentos da operação. A operação de soma necessita de dois argumentos. A operação de raiz quadrada necessita de um argumento. Mensagens desconhecidas são respondidas com Mensagem invalida. Após solicitar as operações, o cliente encerra a conexão. O servidor responde cada operação com o resultado do cálculo. Após ler todas as operações solicitadas (linhas), o servidor encerra a conexão. 8

Exemplo: protocolo Cliente Servidor Cliente Servidor soma <a> <b> <a+b> raiz_quadrada <a> <raiz de a> Cliente Servidor <não especificado> Mensagem invalida 9

Exercício 1) Escreva um programa servidor que lê uma frase e uma palavra enviados pelo cliente e responde com a quantidade de ocorrências da palavra presentes na frase. Teste a implementação com um cliente Telnet e com um programa cliente escrito por você. 2) Especifique o protocolo utilizado pelo jogo jokenpo disponibilizado na página disciplina (jokenpo.zip). 3) Implemente um jogo de par ou ímpar em modo clienteservidor. Um dos jogadores será um usuário humano que deve utilizar um programa cliente. O outro jogador deve ser o próprio programa servidor. Após a implementação, escreva a implementação do protocolo utilizado na aplicação. 10

Servidor multithread Servidores tipicamente devem ser capazes de gerenciar vários clientes de forma simultânea. Caso contrário, cada cliente deve aguardar a sua vez na fila para ser atendido. Para tal, devemos utilizar threads. Threads são linhas de execução paralelas que podem ocorrer em um mesmo programa. Threads também são chamadas de processos leves. 11

Exemplo servidor sem threads require 'socket' serversocket = TCPServer.new(2000) loop { clientsocket = serversocket.accept clientsocket.gets #simula uma operação demorada #como E/S em disco sleep(2); clientsocket.puts('ok') clientsocket.close } 12

Exemplo cliente require 'socket' hostname = 'localhost' port = 2000 threads = [] #armazena as threads que serão criadas inicio = Time.now for i in 1..5 do #cria thread que solicita uma nova conexão com o servidor #cada thread funciona como um programa cliente t = Thread.start(TCPSocket.new(hostname, port)) do socket socket.puts('msg') puts socket.gets socket.close end threads << t #adiciona a thread ao array end 13

Exemplo cliente (cont.) #avisa este programa para aguardar até que todas as threads #tenham terminado sua execução threads.each do t t.join end fim = Time.now #calcula e imprime o tempo de execução puts "#{fim - inicio} s" 14

Cliente fluxo de execução para 3 Programa Principal 3ª thread threads 2ª thread 1ª thread Cria 1ª thread Cria 2ª thread Cria 3ª thread socket.puts(msg) socket.puts(msg) socket.gets() socket.puts(msg) socket.gets() socket.gets() socket.close() socket.close() Aguarda as threads (join) socket.close() Fim 15

Exemplo servidor com threads require 'socket' serversocket = TCPServer.new(2000) puts 'Servidor multithread iniciado' loop { Thread.start(serverSocket.accept) do clientsocket msgcliente = clientsocket.gets #simula uma operação demorada como a gravação em disco sleep(2); #dorme 2 segundos clientsocket.puts('ok') clientsocket.close end } 16

Mutex Devemos estar atentos aos recursos compartilhados por múltiplas threads (variáveis, arquivos, objetos, etc). Quando o acesso simultâneo puder causar inconsistências, podemos utilizar um objeto Mutex para criar blocos de código sincronizados. Estes blocos serão acessados a cada vez por uma única thread. 17

Exemplo servidor sem mutex require 'socket' serversocket = TCPServer.new(2000) puts 'Servidor iniciado' saldo = 100.0 loop { Thread.start(serverSocket.accept) do clientsocket saque = clientsocket.gets.to_f if saldo >= saque sleep(1) saldo = saldo - saque clientsocket.puts('ok') else clientsocket.puts('negado') end clientsocket.close puts " saldo: #{saldo}" end } 18

Exemplo múltiplos clientes require 'socket' realizando saque host = 'localhost' port = 2000 threads = [] for i in 1..2 do t = Thread.start(TCPSocket.new(host, port)) do socket socket.puts('90') puts socket.gets socket.close end threads.push(t) end threads.each do t t.join end 19

Exemplo servidor com mutex require 'socket' serversocket = TCPServer.new(2000) puts 'Servidor iniciado' saldo = 100.0 mutex = Mutex.new loop { Thread.start(serverSocket.accept) do clientsocket saque = clientsocket.gets.to_f mutex.synchronize{ if saldo >= saque sleep(1) saldo = saldo - saque clientsocket.puts('ok') else clientsocket.puts('negado') end puts "saldo #{saldo}" } clientsocket.close end } 20

Exercício 4 Escreva um servidor para um sistema de votação entre três candidatos. O servidor deve ser capaz de processar as seguintes mensagens de entrada: candidatos? Deve retornar uma string com os nomes e números dos candidatos. Cada candidato deve ser separado pelo caractere #. Exemplo de resposta: 1 paulo#2 pedro#3 ana votar n Adiciona um voto para o candidato com número n. Deve retornar a string ok caso a operação seja bem sucedida ou zero em caso contrário. resultado senha Caso senha seja válida, deve retornar uma string com o total de votos de cada candidato. Cada candidato deve ser separado pelo caractere #. No caso de senha inválida, deve retornar zero. A senha é armazenada pelo servidor. Para quaisquer outras mensagens, o servidor deve retornar zero. Escreva um programa que cria 1000 clientes paralelos, onde cada cliente solicita a lista de candidatos e vota em um de forma aleatória. Escreva um programa cliente para obter o resultado da eleição. 21

Transmissão de dados binários Os métodos gets e puts são adequados apenas para dados do tipo string. Para dados binários, devemos utilizar os métodos read e syswrite. read(n): lê n bytes. Os bytes lidos são retornados como uma string codificada em ASCII-8BIT (string binária). Caso o tamanho da string seja menor que n, significa que foi atingido o fim do arquivo (EOF). Retorna nil caso a leitura seja direto no EOF. syswrite(bytes): escreve bytes, o qual que deve ser uma string binária. Retorna a quantidade de bytes escritos. 22

Exemplo: transmissão de arquivo - cliente require 'socket' sock = TCPSocket.new('localhost', 2000) begin nome_arquivo = gets.chomp arquivo = File.new(nome_arquivo, "r") tamanho = File::size(nome_arquivo) bytes_arquivo = arquivo.read(tamanho) sock.puts(nome_arquivo) sock.puts(tamanho.to_s) sock.syswrite(bytes_arquivo) ensure sock.close arquivo.close end 23

Exemplo: transmissão de arquivo - servidor require 'socket' serversocket = TCPServer.new(2000) clientsocket = serversocket.accept begin nome_arquivo = clientsocket.gets.chomp tamanho_arquivo = clientsocket.gets.chomp.to_i bytes_arquivo = clientsocket.read(tamanho_arquivo) arquivo = File.new("copia_#{nome_arquivo}", "wb") arquivo.syswrite(bytes_arquivo) ensure serversocket.close end 24

Exemplo: transmissão de arquivo - protocolo Cliente Servidor <nome do arquivo> <tamanho do arquivo> <bytes> 25

Exemplo protocolo binário Formato das mensagens do cliente: operação argumento 1 argumento 2 Campos (todos com 1 byte): operação: indica a operação desejada, soma (01) ou potência quadrada (02). argumento 1: primeiro termo da soma, ou base da potência. Tipo inteiro. argumento 2: segundo argumento da soma. Não utilizado na potência. Tipo inteiro. 26

Exemplo - protocolo binário O servidor sempre retorna dois bytes que formam um único campo ordenado em network byte order. Este campo armazena o resultado da operação solicitada ou FFFF caso a mensagem de solicitação do cliente não tenha sido reconhecida. 27

Exemplo protocolo binário servidor require 'socket' serversocket = TCPServer.new(2000) begin socket = serversocket.accept loop{ byte_um = socket.read(1).unpack('c')[0] if byte_um == 0x00 campos = socket.read(2).unpack('cc') soma = campos[0] + campos[1] out = [soma].pack('n') elsif byte_um == 0x01 byte_dois = socket.read(1).unpack('c')[0] quadrado = byte_dois * byte_dois out = [quadrado].pack('n') else out = [0xFFFF].pack('n') end socket.syswrite(out) } ensure serversocket.close end 28

Exemplo protocolo binário cliente require 'socket' sock = TCPSocket.new('localhost', 2000) begin #soma msg = [0x00, 203, 85].pack('CCC') sock.syswrite(msg) resposta = sock.read(2).unpack('n')[0] puts "<= #{resposta}" #potencia msg = [0x01, 7].pack('CC') sock.syswrite(msg) resposta = sock.read(2).unpack('n')[0] puts "<= #{resposta}" #nao reconhecida msg = [0x31].pack('C') sock.syswrite(msg) resposta = sock.read(2).unpack('n')[0].to_s(16) puts "<= #{resposta}" ensure sock.close end 29

Exercício Implementar uma aplicação cliente/servidor para download de arquivos usando o protocolo binário descrito a seguir. Formato das mensagens enviadas pelo cliente: ID (1 byte) argumento (20 bytes) ID: indica o tipo da mensagem. Obrigatório. 00 solicita a lista de arquivos disponíveis. 01 solicita um arquivo para download. O nome do arquivo desejado deve ser informado no campo argumento. argumento: informações complementares. Opcional. 30

Exercício 5 Formato das mensagens enviadas pelo servidor: ID (1 byte) tamanho (2 bytes) payload (variável) ID: indica o tipo da mensagem. Obrigatório. 00 informa a lista de arquivos disponíveis. O campo payload contém os nomes dos arquivos, cada um separado pelo caractere $. 01 retorna um arquivo solicitado para download. O campo payload contém os dados (bytes) do arquivo. FF indica que a mensagem de entrada não foi reconhecida pelo servidor. Sem payload. tamanho: indica o tamanho, em bytes, do campo payload. Devido a este campo, só é possível transmitir arquivos com até 64kbytes. Obrigatório. payload: dados solicitados conforme a mensagem de entrada. Opcional. 31

Exercício 5 Terminologia: Sessão: par de mensagens trocadas entre cliente e servidor. Mensagem de entrada: mensagem enviada pelo cliente. Mensagem de retorno: mensagem enviada pelo servidor em resposta a uma mensagem de entrada. Comportamento: Protocolo base: TCP. Uma conexão TCP deve suportar várias sessões do protocolo de aplicação. Uma sessão sempre é iniciada pelo cliente. O servidor sempre deve responder a uma mensagem de entrada. Dica: consulte os métodos Array.pack e String.unpack e o artigo disponível em http://www.happybearsoftware.com/bytemanipulation-in-ruby.html. 32

Classe UDPSocket Socket para transmissão de dados baseados no protocolo UDP. Um UDPSocket pode ser utilizado como cliente (emissor de dados) ou como servidor (receptor de dados), já que o protocolo UDP não é orientado à conexão. Construtor new() Método bind(host, port) Utilizado em um socket servidor, associa o socket a uma interface de rede e a uma porta. Para qualquer interface de rede utilize uma string vazia. Método gets() Utilizado com um socket servidor, lê o próximo pacote de dados. Método recvfrom(maxlen) => data, [sender_info] Utilizado com um socket servidor, lê até maxlen bytes de dados. Retorna os dados lidos e um array com informações do emissor: protocolo, porta, hostname e endereço IP. 33

Classe UDPSocket Método send(data, flags, host, port) Utilizado em um socket servidor ou cliente, envia um pacote de dados ao host especificado pelos parâmetros host e port. Método connect(host, port) Utilizado em um socket cliente. Os parâmetros indicam endereço e porta do destinatário dos dados. Método puts(data) Utilizado em um socket cliente, envia um pacote de dados ao host especificado na chamada ao método connect. 34

Exemplo Servidor echo require 'socket' socket = UDPSocket.new socket.bind("", 2000) loop{ data, sender = socket.recvfrom(1024) s_ip = sender[3] s_port = sender[1] puts "Dados recebidos do cliente #{s_ip}:#{s_port}: #{data} " socket.send(data.upcase, 0, s_ip, s_port) } socket.close 35

Exemplo Cliente echo require 'socket' socket = UDPSocket.new socket.connect('localhost', 2000) msg = gets socket.puts msg puts socket.gets socket.close 36

Exercício 6 Usando sockets UDP, implemente uma aplicação de calculadora semelhante a do exemplo com sockets TCP. 37

Referências http://www.ruby-doc.org/stdlib- 1.9.3/libdoc/socket/rdoc/index.html http://rubylearning.com/satishtalim/ruby_soc ket_programming.html Jones, M. Tim. Sockets programming in Ruby. IBM Developer Works, 2005. 38