Baixe o app para aproveitar ainda mais
Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
Linguagem e Técnica de Programação II Ana Patrícia F. Magalhães Mascarenhas anapatriciamagalhaes@gmail.com 2014.2 Aula 2 – Desenvolvimento cliente/servidor - sockets Agenda Arquitetura Cliente Servidor Sockets Exercícios 2 Arquitetura Cliente-Servidor 193.14.145.01 10.5.0.1 Cliente Servidor Sobre os servidores Entram em execução antes do cliente Utilizam uma porta específica para comunicação, onde recebe solicitações Precisam atender a várias solicitações concomintantes Normalmente possuem um programa mestre e um conjunto de escravos responsáveis por solicitações individuais 4 4 Funcionamento 5 1. Servidor entra em execução, abre porta 2. Servidor aguarda algum cliente 5. Servidor inicia escravo e executa processamento 6 . Servidor retorna ao ponto 2. 3. Cliente entra em execução 4. Cliente faz solicitação 5. Cliente recebe o retorno 6. Cliente finaliza 5 Ainda sobre servidores 6 Solicitações rápidas podem terminar mais cedo independente da ordem que começaram Ex.: Transferência de arquivo Cliente 1: solicita transferência de um arquivo longo Cliente 2: solicita transferência de um arquivo pequeno Cada cliente será executado por um escravo, portanto o cliente 2 pode finalizar antes do 1. 6 Conclusão 7 Servidores são mais complexos que clientes 7 Sockets Dois processos comunicam-se escrevendo dados em sockets e/ou lendo dados de sockets Objeto de software que conecta uma aplicação a um protocolo da camada de rede. Simplifica o desenvolvimento do programa, liberando o desenvolvedor das tarefas realizadas pela camada de transporte (usa ex. protocolo TCP ou UDP) Para identificar um processo numa rede é necessário: Endereço IP – do host que executa o outro processo Número da porta – identifica qual o processo local do host para o qual a mensagem será despachada 8 Programação com sockets API Sockets são explicitamente criados, usados e liberados por apls paradigma cliente/servidor dois tipos de serviço de transporte via API Sockets datagrama não confiável fluxo de bytes, confiável 9 uma interface (uma “porta”), local ao hospedeiro, criada por e pertencente à aplicação, e controlado pelo SO, através da qual um processo de aplicação pode tanto enviar como receber mensagens para/de outro processo de aplicação (remoto ou local) socket Meta: aprender a construir aplicações cliente/servidor que se comunicam usando sockets Programação com sockets usando TCP Cliente deve contactar servidor processo servidor deve antes estar em execução servidor deve antes ter criado socket (porta) que aguarda contato do cliente Quando cliente cria socket: TCP do cliente estabelece conexão com TCP do servidor Quando contatado pelo cliente, o TCP do servidor cria socket novo para que o processo servidor possa se comunicar com o cliente permite que o servidor converse com múltiplos clientes 10 TCP provê transferência confiável, ordenada de bytes (“tubo”) entre cliente e servidor ponto de vista da aplicação Comunicação entre sockets 11 Conectando-se a um Servidor com TCP Para se conectar a um servidor usa-se um socket. Para se criar um socket usa-se o construtor da classe Socket(String host, int porta). Para ler de um socket usa-se a stream de entrada do socket obtida por getInputStream() Para escrever em um socket usa-se a stream de saída do socket obtida por getOutputStream() 12 Esquema do Cliente TCP Abre-se uma conexão: Socket s = new Socket(“www”, 80); Escreve-se a requisição no socket: s.getOutputStream().writeln(“GET / HTTP1.1”) Consome-se a resposta do servidor s.getInputStream().readln() Fecha-se a conexão s.close() 13 A Classe InetAddress A classe InetAddress representa um endereço IP em Java. Ela faz as chamadas necessárias ao DNS e realiza as conversões necessárias de nome para endereço IP e vice-versa. static InetAddress getByName(String host) static InetAddress[] getAllByName(String host) 14 A Classe InetAddress A classe fornece um conjunto de métodos para: Retornar o array de bytes com os quatro bytes de um endereço IP byte[] getAddress() Retornar o endereço IP como uma string de números decimais separados por pontos String getHostAddress() Retornar o nome do servidor String getHostName() 15 Exemplo de aplicação cliente-servidor cliente lê linha da entrada padrão (fluxo doUsuário), envia para servidor via socket (fluxo paraServidor) servidor lê linha do socket servidor converte linha para letras maiúsculas, devolve para o cliente cliente lê linha modificada do socket (fluxo doServidor), imprime-a 16 Interações cliente/servidor usando o TCP 17 aguarda chegada de pedido de conexão socketConexão = socketRecepção.accept() cria socket, porta=x, para receber pedido: socketRecepção = ServerSocket () cria socket, abre conexão a nomeHosp, porta=x socketCliente = Socket() fecha socketConexão lê resposta de socketCliente fecha socketCliente Servidor (executa em nomeHosp) Cliente Envia pedido usando socketCliente lê pedido de socketConexão escreve resposta para socketConexão TCP setup da conexão Exemplo: cliente Java (TCP) 18 import java.io.*; import java.net.*; class ClienteTCP { public static void main(String argv[]) throws Exception { String frase; String fraseModificada; BufferedReader doUsuario = new BufferedReader(new InputStreamReader(System.in)); Socket socketCliente = new Socket(”nomeHosp", 6789); DataOutputStream paraServidor = new DataOutputStream(socketCliente.getOutputStream()); Cria fluxo de entrada Cria socket de cliente, conexão ao servidor Cria fluxo de saída ligado ao socket Exemplo: cliente Java (TCP), cont. 19 BufferedReader doServidor = new BufferedReader(new InputStreamReader(socketCliente.getInputStream())); frase = doUsuario.readLine(); paraServidor.writeBytes(frase + '\n'); fraseModificada = doServidor.readLine(); System.out.println(”Do Servidor: " + fraseModificada); socketCliente.close(); } } Cria fluxo de entrada ligado ao socket Envia linha ao servidor Lê linha do servidor Implementando Servidores Para implementar servidores, o Java possui uma classe chamada ServerSocket. Para criar um ServerSocket, é preciso indicar, no construtor, qual a porta que o servidor estará escutando ServerSocket(int porta) throws IOException 20 Implementando Servidores O servidor deve ficar monitorando a porta até que chegue uma requisição de comunicação. O método a seguir bloqueia a execução e aguarda uma requisição de comunicação. Então ele retorna um novo socket para a conexão estabelecida. Socket accept() throws IOException 21 Implementando Servidores De posse do novo socket, a comunicação se dá como no caso da aplicação cliente. Eventualmente pode-se querer fechar o socket servidor: void close() throws IOException 22 Esquema do Servidor Cria-se um ServerSocket ServerSocket server = new ServerSocket(80); Aguarda-se por uma requisição cliente Socket s = server.accept(); Opera-se como um socket normal s.getOutputStream().write(); s.close(); Fecha-se o serviço server.close(); 23 Exemplo: servidor Java (TCP) 24 import java.io.*; import java.net.*; class servidorTCP { public static void main(String argv[]) throws Exception { String fraseCliente; StringfFraseMaiusculas; ServerSocket socketRecepcao = new ServerSocket(6789); while(true) { Socket socketConexao = socketRecepcao.accept(); BufferedReader doCliente = new BufferedReader(new InputStreamReader(socketConexao.getInputStream())); Cria socket para recepção na porta 6789 Aguarda, no socket para recepção, o contato do cliente Cria fluxo de entrada, ligado ao socket Exemplo: servidor Java (TCP), cont 25 DataOutputStream paraCliente = new DataOutputStream(socketConexão.getOutputStream()); fraseCliente= doCliente.readLine(); fraseEmMaiusculas= fraseCliente.toUpperCase() + '\n'; paraClient.writeBytes(fraseEmMaiusculas); } } } Lê linha do socket Cria fluxo de saída, ligado ao socket Escreve linha ao socket Final do elo while, volta ao início e aguarda conexão de outro cliente Números de Porta Números de porta permite endereçar processos distintos em uma mesma máquina. Algumas portas de processos de aplicações mais populares para a Web são HTTP = 80, SMTP = 25 Para aplicações particulares procure usar portas com números entre 1024 e 65535 26 Programação com sockets usando UDP UDP: não tem “conexão” entre cliente e servidor não tem “handshaking” remetente coloca explicitamente endereço IP e porta do destino servidor deve extrair endereço IP, porta do remetente do datagrama recebido UDP: dados transmitidos podem ser recebidos fora de ordem, ou perdidos 27 UDP provê transferência não confiável de grupos de bytes (“datagramas”) entre cliente e servidor ponto de vista da aplicação Conectando-se a um Servidor com UDP Para se conectar a um servidor UDP é necessário um socket para o protocolo UDP Um socket UDP não estabelece conexão com o processo servidor na sua construção: DatagramSocket socket = new DatagramSocket(); 28 Conectando-se a um Servidor UDP Para enviar dados para um servidor UDP você precisa usar um datagrama. byte[] data = new byte[DATAGRAM_SIZE]; DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(“DNS”), 1111); Para enviar o datagrama usa-se: socket.send(packet) 29 Conectando-se a um Servidor UDP Para receber um datagrama, usa-se o método bloqueante: socket.receive(new DatagramPacket(data, data.length)) Ao fim da comunicação deve-se fechar o socket: socket.close() 30 Criando um Servidor UDP Deve-se construir um DatagramSocket na porta desejada DatagramSocket server = new DatagramSocket(1111); Receber os dados na porta indicada packet = new DatagramPacket(data, data.length) server.receivePacket(packet) InetAddress clientAdd = packet.getAddress() int clientPort = packet.getPort(); 31 Criando um Servidor UDP Enviar dados na mesma porta server.sendPacket(packet, packet.length, clientAdd, clientPort) Eventualmente fechar o servidor server.close() 32 Interações cliente/servidor usando o UDP 33 fecha socketCliente Servidor (executa em nomeHosp) lê resposa do socketCliente cria socket, socketCliente = DatagramSocket() Cliente cria, endereça (nomeHosp, porta=x, envia pedido em datagrama usando socketCliente cria socket, porta=x, para pedido que chega: socketServidor = DatagramSocket() lê pedido do socketServidor escreve resposta ao socketServidor especificando endereço IP, número de porta do cliente Exemplo: cliente Java (UDP) 34 import java.io.*; import java.net.*; class clienteUDP { public static void main(String args[]) throws Exception { BufferedReader doUsuario= new BufferedReader(new InputStreamReader(System.in)); DatagramSocket socketCliente = new DatagramSocket(); InetAddress IPAddress = InetAddress.getByName(”nomeHosp"); byte[] dadosEnvio = new byte[1024]; byte[] dadosRecebidos = new byte[1024]; String frase = doUsuario.readLine(); dadosEnvio = frase.getBytes(); Cria fluxo de entrada Cria socket de cliente Traduz nome de hospedeiro ao endereço IP usando DNS Exemplo: cliente Java (UDP) cont. 35 DatagramPacket pacoteEnviado = new DatagramPacket(dadosEnvio, dadosEnvio.length, IPAddress, 9876); socketCliente.send(pacoteEnviado); DatagramPacket pacoteRecebido = new DatagramPacket(dadosRecebidos, dadosRecebidos.length); socketCliente.receive(pacoteRecebido); String fraseModificada = new String(pacoteRecebido.getData()); System.out.println(“Do Servidor:" + fraseModificada); socketCliente.close(); } } Cria datagrama com dados para enviar, comprimento, endereço IP, porta Envia datagrama ao servidor Lê datagrama do servidor Exemplo: servidor Java (UDP) 36 import java.io.*; import java.net.*; class servidorUDP { public static void main(String args[]) throws Exception { DatagramSocket socketServidor = new DatagramSocket(9876); byte[] dadosRecebidos = new byte[1024]; byte[] dadosEnviados = new byte[1024]; while(true) { DatagramPacket pacoteRecebido = new DatagramPacket(dadosRecebidos, dadosRecebidos.length); socketServidor.receive(pacoteRecebido); Cria socket para datagramas na porta 9876 Aloca memória para receber datagrama Recebe datagrama Exemplo: servidor Java (UDP), cont 37 String frase = new String(pacoteRecebido.getData()); InetAddress IPAddress = pacoteRecebido.getAddress(); int porta = pacoteRecebido.getPort(); String fraseEmMaiusculas = frase.toUpperCase(); dadosEnviados = fraseEmMaiusculas.getBytes(); DatagramPacket pacoteEnviado = new DatagramPacket(dadosEnviados, dadosEnviados.length, IPAddress, porta); socketServidor.send(pacoteEnviado); } } } Obtém endereço IP, no. de porta do remetente Escreve datagrama no socket Fim do elo while, volta ao início e aguarda chegar outro datagrama Cria datagrama p/ enviar ao cliente Primeiro exercício para nota Implemente um socket tcp cliente e um servidor que funcione da seguinte maneira: O cliente deve solicitar dados de identificação de um aluno: ano de inclusão, primeiro nome, ultimo nome e data de nascimento O servidor receberá os dados montará uma senha para o aluno e enviará como resposta para o cliente. A senha será montada concatenando o primeiro nome com “.” com ultimo nome com “.” com o ano de inclusão O cliente recebe a mensagem e mostra na tela para o usuário O servidor fica aguardando novas conexões 38 Programação com sockets: referências Tutorial de linguagem C (áudio/slides): “Unix Network Programming” (J. Kurose), http://manic.cs.umass.edu/~amldemo/courseware/intro. Tutoriais Java: “All About Sockets” (Tutorial da Sun), http://www.javaworld.com/javaworld/jw-12-1996/jw-12-sockets.html “Socket Programming in Java: a tutorial,” http://www.javaworld.com/javaworld/jw-12-1996/jw-12-sockets.html 39
Compartilhar