Programação com Sockets

Propaganda
Redes de Computadores
Programação com Sockets
Prof. Othon Batista ([email protected])‫‏‬
Página 1
Roteiro
•
•
•
•
•
•
Introdução
A Arquitetura TCP/IP
O Protocolo IP
O Protocolo UDP
O Protocolo TCP
Qual Protocolo Usar: UDP
ou TCP?
• Socket com TCP
• Socket com TCP: Exemplo
de Aplicação
• Socket com UDP
• Socket com UDP: Exemplo
de Aplicação
• Servidor Web Simples
Prof. Othon Batista ([email protected])‫‏‬
Página 2
Introdução
Objetivo: aprender a construir aplicações
cliente/servidor usando sockets.
• Os sockets apareceram pela primeira vez em uma
implementação do BSD Unix 4.1 em 1981.
– Devem ser explicitamente criados, usados e liberados.
– Paradigma cliente/servidor.
– São a forma mais usada de comunicação entre processos
(IPC – Inter Process Communication).
• Há dois tipos de sockets: UDP e TCP.
Prof. Othon Batista ([email protected])‫‏‬
Página 3
A Arquitetura TCP/IP
Aplicações
cliente/servidor
Serviço orientado à
conexão e confiável.
SEGMENTO
Aplicação
TCP
UDP
IP
Rede Física
Serviço não orientado à
conexão e não confiável.
DATAGRAMA
Serviço não orientado à
conexão e não confiável.
DATAGRAMA
• Comunicação através de endereços IP e portas
lógicas.
Prof. Othon Batista ([email protected])‫‏‬
Página 4
A Arquitetura TCP/IP
• Os endereços IP são formados por quatro números,
tipicamente separados por pontos.
• Cada número tem o tamanho de 1 byte (0 – 255).
• Exemplo: 10.125.3.45
• Alguns endereços IP são reservados (não nos
interessam neste momento)!
• Há também os nomes simbólicos, que devem ser
traduzidos para endereços IP por algum serviço, tal
como o DNS. Exemplo: www.fib.br.
Prof. Othon Batista ([email protected])‫‏‬
Página 5
Arquitetura TCP/IP
• Convenção para os números de portas:
– 0 até 1023 ⇒ portas privilegiadas;
– 1024 até 65535 ⇒ portas sem restrições.
• Algumas portas privilegiadas:
–
–
–
–
–
FTP ⇒ 20 e 21
Telnet ⇒ 23
SMTP ⇒ 25
POP3 ⇒ 110
DNS ⇒ 53
Não use estas portas.
A não ser que você saiba
o que está fazendo!
Prof. Othon Batista ([email protected])‫‏‬
Página 6
O Protocolo IP
•
•
•
•
•
Camada mais baixa da arquitetura TCP/IP.
Não é fim-a-fim.
Não orientada à conexão.
Usada pelos protocolos UDP e TCP.
Serviço de datagrama não confiável:
– a entrega de um datagrama não é garantida;
– os datagramas podem ser entregues fora de ordem;
– podem ser recebidos datagramas duplicados.
• A confiabilidade é dada nas camadas acima!
Prof. Othon Batista ([email protected])‫‏‬
Página 7
O Protocolo UDP
datagramas UDP
•
•
•
•
•
•
Usado diretamente pelos programas.
É fim-a-fim.
Não orientado à conexão.
Serviço de datagrama não confiável.
Mais ágil de TCP.
Usado por: DNS, NFS, SNMP, RIP...
Prof. Othon Batista ([email protected])‫‏‬
Página 8
O Protocolo TCP
segmentos TCP
•
•
•
•
•
Usado diretamente pelos programas.
É fim-a-fim.
Orientado à conexão.
Serviço confiável.
Usado por: FTP, TELNET, SMTP, POP3...
Prof. Othon Batista ([email protected])‫‏‬
Página 9
Qual Protocolo Usar : UDP ou TCP?
• TCP deve ser escolhido para aplicações que
necessitam de transferência de dados confiável, por
exemplo:
– transferência de arquivos (FTP);
– terminais virtuais (TELNET).
• UDP deve ser escolhida para:
– aplicações simples de pedido/resposta (DNS);
– aplicações que podem tolerar transmissões de dados não
confiáveis (protocolos de roteamento, tal como RIP).
Prof. Othon Batista ([email protected])‫‏‬
Página 10
Socket com TCP
Um socket é uma porta entre o processo de
aplicação e um protocolo de transporte fim-a-fim.
controlado pelo
programador de
aplicação
controlado
pelo sistema
operacional
processo
processo
socket
TCP com
buffers,
variáveis
Cliente
Internet
socket
TCP com
buffers,
variáveis
controlado pelo
programador de
aplicação
controlado
pelo sistema
operacional
Servidor
Prof. Othon Batista ([email protected])‫‏‬
Página 11
Socket com TCP
• O processo servidor deve
estar em execução.
• O servidor deve ter criado
socket que aguarda contato
do cliente.
• O cliente cria socket TCP
local.
• O cliente especifica
endereço IP, número de
porta do processo servidor.
• Quando o cliente cria um
socket, o 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
– o servidor conversa com
múltiplos clientes
Prof. Othon Batista ([email protected])‫‏‬
Página 12
Socket com TCP
ponto de vista da aplicação
TCP provê transferência
confiável, ordenada de bytes
(“tubo”) entre cliente e servidor
Prof. Othon Batista ([email protected])‫‏‬
Página 13
Socket com TCP:
Exemplo de Aplicação
do_usuario
do_servidor
Fluxo de entrada: seqüência
de bytes recebida pelo
processo.
Fluxo de saída: seqüência de
bytes transmitida pelo
processo.
para_servidor
• Cliente lê linha da entrada
padrão (doUsuário),
envia para servidor via
socket (paraServidor).
• Servidor lê linha do socket.
• Servidor converte linha
para letras maiúsculas,
devolve para o cliente.
• Cliente lê linha modificada
do socket (doServidor),
imprime-a.
socket do cliente
Prof. Othon Batista ([email protected])‫‏‬
Página 14
Servidor
Socket com TCP:
Exemplo de Aplicação
(executa em nomeHosp)‫‏‬
cria socket,
porta=x, para
receber pedido:
socketRecepção =
ServerSocket ()‫‏‬
TCP
aguarda chegada de
configuração
pedido de conexão
socketConexão =
socketRecepção.accept()‫‏‬
lê pedido de
socketConexão
escreve resposta
para socketConexão
fecha
socketConexão
Cliente
cria socket,
abre conexão a nomeHosp, porta=x
socketCliente =
Socket()‫‏‬
Envia pedido usando
socketCliente
lê resposta de
socketCliente
fecha
socketCliente
Prof. Othon Batista ([email protected])‫‏‬
Página 15
Socket com TCP:
Exemplo de Aplicação (Cliente)‫‏‬
import java.io.*;
import java.net.*;
class ClienteTCP {
public static void main(String argv[]) throws Exception
{
String frase;
String fraseModificada;
Cria
fluxo de entrada
Cria
socket de cliente,
conexão ao servidor
Cria
fluxo de saída
ligado ao socket
BufferedReader doUsuario =
new BufferedReader(new InputStreamReader(System.in));
Socket socketCliente = new Socket(”nomeHosp", 6789);
DataOutputStream paraServidor =
new DataOutputStream(socketCliente.getOutputStream());
Prof. Othon Batista ([email protected])‫‏‬
Página 16
Socket com TCP:
Exemplo de Aplicação (Cliente)‫‏‬
Cria
fluxo de entrada
ligado ao socket
BufferedReader doServidor =
new BufferedReader(new
InputStreamReader(socketCliente.getInputStream()));
frase = doUsuario.readLine();
Envia linha
ao servidor
paraServidor.writeBytes(frase + '\n');
fraseModificada = doServidor.readLine();
Lê linha
do servidor
System.out.println(”Do Servidor: " + fraseModificada);
socketCliente.close();
}
}
Prof. Othon Batista ([email protected])‫‏‬
Página 17
Socket com TCP:
Exemplo de Aplicação (Servidor)‫‏‬
import java.io.*;
import java.net.*;
class servidorTCP {
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
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()));
Prof. Othon Batista ([email protected])‫‏‬
Página 18
Socket com TCP:
Exemplo de Aplicação (Servidor)‫‏‬
Cria fluxo
de saída, ligado
ao socket
DataOutputStream paraCliente =
new DataOutputStream(socketConexão.getOutputStream());
Lê linha
do socket
fraseCliente= doCliente.readLine();
fraseEmMaiusculas= fraseCliente.toUpperCase() + '\n';
Escreve linha
ao socket
paraClient.writeBytes(fraseEmMaiusculas);
}
}
}
Final do elo while,
volta ao início e aguarda
conexão de outro cliente
Prof. Othon Batista ([email protected])‫‏‬
Página 19
Socket com UDP
•
•
•
•
UDP não estabelece conexão.
remetente coloca explicitamente endereço IP e
porta do destino.
servidor deve extrair endereço IP, porta do
remetente do datagrama recebido.
Os dados transmitidos podem ser recebidos fora de
ponto de vista da aplicação
ordem, ou perdidos.
UDP provê transferência
não confiável de grupos
de bytes (“datagramas”)
entre cliente e servidor
Prof. Othon Batista ([email protected])‫‏‬
Página 20
Socket com UDP
Servidor
(executa em nomeHosp)‫‏‬
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
Cliente
cria socket,
socketCliente =
DatagramSocket()‫‏‬
cria, endereça (nomeHosp, porta=x,
envia pedido em datagrama
usando socketCliente
lê resposa do
socketCliente
fecha
socketCliente
Prof. Othon Batista ([email protected])‫‏‬
Página 21
Socket com UDP:
Exemplo de Aplicação (Cliente)‫‏‬
Prof. Othon Batista ([email protected])‫‏‬
Página 22
Socket com UDP:
Exemplo de Aplicação (Cliente)‫‏‬
import java.io.*;
import java.net.*;
Cria
fluxo de entrada
Cria
socket de cliente
Traduz nome de
hospedeiro ao
endereço IP
usando DNS
class clienteUDP {
public static void main(String args[]) throws Exception
{
BufferedReader do Usuario=
new BufferedReader(new InputStreamReader(System.in));
DatagramSocket socketCliente = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName(”nomeHosp");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String frase = doUsuario.readLine();
sendData = frase.getBytes();
Prof. Othon Batista ([email protected])‫‏‬
Página 23
Socket com UDP:
Exemplo de Aplicação (Cliente)‫‏‬
Cria datagrama com
dados para enviar,
comprimento,
endereço IP, porta
Envia datagrama
ao servidor
DatagramPacket pacoteEnviado =
new DatagramPacket(dadosEnvio, dadosEnvio.length,
IPAddress, 9876);
socketCliente.send(pacoteEnviado);
DatagramPacket pacoteRecebido =
new DatagramPacket(dadosRecebidos, dadosRecebidos.length);
Lê datagrama
do servidor
socketCliente.receive(pacoteRecebido);
String fraseModificada =
new String(pacoteRecebido.getData());
System.out.println(”Do Servidor:" + fraseModificada);
socketCliente.close();
}
}
Prof. Othon Batista ([email protected])‫‏‬
Página 24
Socket com UDP:
Exemplo de Aplicação (Servidor)‫‏‬
Prof. Othon Batista ([email protected])‫‏‬
Página 25
Socket com UDP:
Exemplo de Aplicação (Servidor)‫‏‬
import java.io.*;
import java.net.*;
Cria socket
para datagramas
na porta 9876
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];
Aloca memória para
receber datagrama
Recebe
datagrama
while(true)
{
DatagramPacket pacoteRecebido =
new DatagramPacket(dadosRecebidos,
dadosRecebidos.length);
socketServidor.receive(pacoteRecebido);
Prof. Othon Batista ([email protected])‫‏‬
Página 26
Socket com UDP:
Exemplo de Aplicação (Servidor)‫‏‬
String frase = new String(pacoteRecebido.getData());
Obtém endereço
IP, no. de porta
do remetente
InetAddress IPAddress = pacoteRecebido.getAddress();
int porta = pacoteRecebido.getPort();
String fraseEmMaiusculas = frase.toUpperCase();
dadosEnviados = fraseEmMaiusculas.getBytes();
Cria datagrama p/
enviar ao cliente
Escreve
datagrama
no socket
}
DatagramPacket pacoteEnviado =
new DatagramPacket(dadosEnviados,
dadosEnviados.length, IPAddress, porta);
socketServidor.send(pacoteEnviado);
}
}
‘
Fim do elo while,
volta ao início e aguarda
chegar outro datagrama
Prof. Othon Batista ([email protected])‫‏‬
Página 27
Servidor Web Simples
• Funções do servidor Web:
– Trata apenas um pedido HTTP por vez
– Aceita e examina o pedido HTTP
– Recupera o arquivo pedido do sistema de arquivos do
servidor
– Cria uma mensagem de resposta HTTP consistindo do
arquivo solicitado precedido por linhas de cabeçalho
– Envia a resposta diretamente ao cliente.
Prof. Othon Batista ([email protected])‫‏‬
Página 28
Servidor Web Simples
Contém a classe
StringTokenizer que é
usada para examinar
o pedido
Primeira linha da mensagem
de pedido HTTP e
Nome do arquivo solicitado
Aguarda conexão
do cliente
import java.io.*;
import java.net.*;
import java.util.*;
class WebServer {
public static void main(String argv[]) throws Exception
{
String requestMessageLine;
String fileName;
ServerSocket listenSocket = new ServerSocket(6789);
Socket connectionSocket = listenSocket.accept();
Cria fluxo
de Entrada
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(
connectionSocket.getInputStream()));
Cria fluxo
de Saída
DataOutputStream outToClient =
new DataOutputStream(
connectionSocket.getOutputStream());
Prof. Othon Batista ([email protected])‫‏‬
Página 29
Servidor Web Simples
Lê a primeira linha do
pedido HTTP que deveria
ter o seguinte formato:
GET file_name HTTP/1.0
Examina a primeira linha
da mensagem para extrair
o nome do arquivo
Associa o fluxo inFile
ao arquivo fileName
Determina o tamanho do
arquivo e constrói um vetor
de bytes do mesmo tamanho
requestMessageLine = inFromClient.readLine();
StringTokenizer tokenizedLine =
new StringTokenizer(requestMessageLine);
if (tokenizedLine.nextToken().equals("GET")){
fileName = tokenizedLine.nextToken();
if (fileName.startsWith("/") == true )‫‏‬
fileName = fileName.substring(1);
File file = new File(fileName);
int numOfBytes = (int) file.length();
FileInputStream inFile = new FileInputStream (
fileName);
byte[] fileInBytes = new byte[];
inFile.read(fileInBytes);
Prof. Othon Batista ([email protected])‫‏‬
Página 30
Servidor Web Simples
Inicia a construção da
mensagem de resposta
outToClient.writeBytes(
"HTTP/1.0 200 Document Follows\r\n");
if (fileName.endsWith(".jpg"))‫‏‬
outToClient.writeBytes("Content-Type: image/jpeg\r\n");
if (fileName.endsWith(".gif"))‫‏‬
outToClient.writeBytes("Content-Type:
image/gif\r\n");
outToClient.writeBytes("Content-Length: " + numOfBytes +
"\r\n");
outToClient.writeBytes("\r\n");
Transmissão do
cabeçalho da resposta
HTTP.
outToClient.write(fileInBytes, 0, numOfBytes);
connectionSocket.close();
}
else System.out.println("Bad Request Message");
}
}
Prof. Othon Batista ([email protected])‫‏‬
Página 31
Download