Redes de Computadores II
Programação
Programação com
com Sockets
Sockets
em
em Python
Python
Prof. Ricardo Couto A. da Rocha
[email protected] UFG – Regional de Catalão
v.2016
Camada de Transporte
Arquitetura TCP/IP
APLICAÇÃO
TRANSPORTE
REDE
ENLACE/FÍSICA
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 2
Programação de sockets
●
Objetivo: aprender a construir aplicações cliente-servidor
que se comunicam usando sockets
●
Socket API
– Introduzida no BSD4.1 UNIX, 1981
– Explicitamente criados, usados e liberados pelas aplicações
– Paradigma cliente-servidor
– Dois tipos de serviço de transporte via socket API:
– Datagrama não confiável
– Confiável, orientado a cadeias de bytes
Socket
Uma interface local, criada por aplicações, controlada pelo OS (uma
“porta”) na qual os processos de aplicação podem tanto enviar quanto
receber mensagens de e para outro processo de aplicação (local ou
remoto)
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 3
Chamadas de Sistema
Chamada Tipo Descrição
socket
socket(...) C ou S Cria um socket
bind(...) S ou S associa uma porta com um socket
connect(...) C estabelece uma conexão por um socket a um destino
listen(...) S solicita a espera por conexões/pacotes em uma certa
porta
accept() S aceita conexões recebidos em uma porta
Send(...) C ou S envia ou recebe bytes em uma conexão (TCP)
recv(...) (TCP)
sendto(...) / C ou S envia ou recebe bytes em um socket orientado a
recvfrom(...) (UDP) datagramas (UDP)
close() C ou S solicita o fechamento do socket (sempre unilateral)
As chamadas de sistema são as construções de mais baixo
nível (do SO) para gerenciar sockets.
As linguagens e bibliotecas oferecem APIs que podem
esconder diversos detalhes das chamadas acima.
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 4
Velocidade de Transmissão
●
Velocidade do meio
– Efetiva na camada de transporte, e não na camada
de enlace
●
Capacidade de transmissão (envio de send()) no
socket
●
Capacidade de recepção (invocação de recv())
no socket
●
Tamanho dos buffers (em teoria)
●
Qual é o efeito de um buffer muito pequeno?
●
Qual é o efeito de um buffer infinito?
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 5
Programação de sockets TCP
●
Socket: uma porta entre o processo de aplicação e o
protocolo de transporte fim-a-fim (UDP or TCP)
●
Serviço TCP: transferência confiável de bytes de um
processo para outro
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 6
Programação de sockets TCP
●
Cliente deve contatar o servidor
Processo servidor já deve estar em execução
Servidor deve ter criado socket (porta) que aceita o contato do cliente
●
Cliente contata o servidor
Criando um socket TCP local
Especificando endereço IP e número da porta do processo servidor
Quando o cliente cria o socket: cliente TCP estabelece conexão com o TCP
do servidor
●
Quando contatado pelo cliente, o TCP do servidor cria um novo socket
para o processo servidor comunicar-se com o cliente
Permite ao servidor conversar com múltiplos clientes
Números da porta de origem são usados para distinguir o cliente
Ponto de vista da aplicação
TCP fornece a transferência confiável, em ordem de bytes (“pipe”) entre o
cliente e o servidor
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 7
Jargão stream
●
Um stream é uma seqüência de caracteres que
fluem para dentro ou para fora de um processo
●
Um stream de entrada é agregado a alguma fonte
de entrada para o processo, ex.: teclado ou
socket
●
Um stream de saída é agregado a uma fonte de
saída, ex.: monitor ou socket
●
No TCP, antes do início de uma conexão, é
necessário o handshake, com o qual cliente TCP e
servidor TCP se preparam para uma conversa.
– Handshake é transparente para aplicações
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 8
Programação de sockets TCP
Exemplo de aplicação cliente-
servidor:
1. Cliente lê linha da entrada-padrão do
sistema (inFromUser stream), envia
para o servidor via socket
(outToServer stream)
2. Servidor lê linha do socket
3. Servidor converte linha para letras sh ak
e
nd
maiúsculas e envia de volta ao cliente h a
y
- wa
e
re
4. Cliente lê a linha modificada através do Th
(inFromServer stream)
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 9
Interação cliente-servidor TCP
Servidor Cliente
rodando em hostid
Cria socket port=x,
para requisição entrante:
welcomeSocket =
ServerSocket()
configuração da
Criar socket conectado a
Esperar por requisição conexão TCP
hostid, port=x
de conexão entrante: clientSocket =
connectionSocket = Socket()
welcomeSocket.accept
()
Enviar requisição
usando clientSocket
Ler requisição de
connectionSocket
Escrever resposta para Ler resposta de
connectionSocket clientSocket
protocolo da aplicação
Fechar
Fechar clientSocket
connectionSocket
um cliente por vez
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 10
Cliente TCP Servidor TCP
origem destinatário
/n a r v a l a p a
/n a r v a l a p a
/n a r v a l a p a
/n a r v a l a p a
/n a r v a l a p a
TCP
TCPoferece
oferecegarantias
garantiascontracontraerros:
erros:bytesbyteschegarão
chegarãocorretos
corretoseena naordem
ordem
que foram
que foram enviados.
Prof. Dr. enviados. Não
Não da
Ricardo Couto Antuneshá nenhuma
háRocha
nenhuma garantia
garantia
- Depto. de Ciência de temporização.
de temporização.
da Computação – Regional de Catalão
Exemplo: Cliente Python
import socket
SERVIDOR = 'localhost'
PORTA = 9898
print('Iniciando cliente')
socketCliente =
socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
socketCliente.connect((SERVIDOR, PORTA))
socketCliente.sendall(b'Echo\n')
data = socketCliente.recv(1024)
print('Resposta: ', data.decode("utf-8"))
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão
Exemplo: Servidor Python
socketServidor = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
socketServidor.bind(('', 9898))
socketServidor.listen(1)
print("...esperando conexoes ...")
conexao, endereco = socketServidor.accept()
while True:
dado = conexao.recv(1024)
if not dado: break
print(" >> ", dado)
conexao.sendall(b"ok")
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão
Exemplo: cliente Java (TCP)
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String argv[]) throws Exception
{
String sentence;
String modifiedSentence;
Cria
stream de entrada BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
Cria
socket cliente, Socket clientSocket = new Socket("hostname", 6789);
conecta ao servidor
DataOutputStream outToServer =
Cria new DataOutputStream(clientSocket.getOutputStream());
stream de saída
ligado ao socket
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 14
Exemplo: cliente Java (TCP)
Cria
stream de entrada BufferedReader inFromServer =
ligado ao socket new BufferedReader( new
InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
Envia linha
outToServer.writeBytes(sentence + '\n');
para o servidor
Lê linha modifiedSentence = inFromServer.readLine();
do servidor
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 15
Exemplo: servidor Java (TCP)
import java.io.*;
import java.net.*;
class TCPServer {
public static void main( String argv[]) throws Exception
{
String clientSentence;
Cria String capitalizedSentence;
socket servidor
ServerSocket welcomeSocket = new ServerSocket(6789);
na porta 6789
while (true) {
Espera, no socket
servidor, por Socket connectionSocket = welcomeSocket.accept();
contato do cliente
BufferedReader inFromClient =
Cria stream de new BufferedReader( new
entrada ligado InputStreamReader(connectionSocket.getInputStream()));
ao socket
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 16
Exemplo: servidor Java (TCP)
Cria stream de
saída ligado ao
socket DataOutputStream outToClient =
new DataOutputStream(connectionSocket.getOutputStream());
Lê linha do
clientSentence = inFromClient.readLine();
socket
capitalizedSentence = clientSentence.toUpperCase() + '\n';
Escreve linha outToClient.writeBytes(capitalizedSentence);
para o socket }
}
}
Fim do while loop,
retorne e espere por
outra conexão do cliente
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 17
Programação de sockets UDP
●
UDP: não há conexão entre o cliente e o servidor
Não existe apresentação
Transmissor envia explicitamente endereço IP e porta
de destino em cada mensagem
Servidor deve extrair o endereço IP e porta do
transmissor de cada datagrama recebido
●
UDP: dados transmitidos podem ser recebidos
fora de ordem ou perdidos
Ponto de vista da aplicação
UDP fornece a transferência não confiável de grupos de
bytes (datagramas) entre o cliente e o servidor
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 18
Interação cliente-servidor: UDP
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 19
Exemplo: cliente Java (UDP)
●
Lado cliente
●
Lado servidor
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 20
Exemplo: cliente Java (UDP)
import java.io.*;
import java.net.*;
class UDPClient {
public static void main (String args[])
throws Exception {
Cria
stream de entrada BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
Cria
socket cliente DatagramSocket clientSocket = new DatagramSocket();
Translada InetAddress IPAddress = InetAddress.getByName("estacao.ufg.br");
nome do
byte[] sendData = new byte[1024];
hospedeiro para byte[] receiveData = new byte[1024];
endereço IP
usando DNS String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 21
Exemplo: cliente Java (UDP)
Cria datagrama com
dados a enviar,
tamanho, endereço
IP porta DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length,
IPAddress, 9876);
Envia datagrama clientSocket.send(sendPacket);
para servidor DatagramPacket receivePacket =
new DatagramPacket(receiveData,
receiveData.length);
Lê datagrama
clientSocket.receive(receivePacket);
do servidor
String modifiedSentence =
new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 22
Exemplo: servidor Java (UDP)
import java.io.*;
import java.net.*;
class UDPServer {
public static void main (String args[]) throws Exception
Cria {
socket datagrama
DatagramSocket serverSocket = new DatagramSocket(9876);
na porta 9876
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true)
{
Cria espaço para DatagramPacket receivePacket =
datagramas recebidos new DatagramPacket(receiveData, receiveData.length);
Recebe serverSocket.receive(receivePacket);
datagrama
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 23
Exemplo: servidor Java (UDP)
String sentence = new String(receivePacket.getData());
Obtém endereço IP
InetAddress IPAddress = receivePacket.getAddress();
e número da porta
do transmissor int port = receivePacket.getPort();
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
Cria datagrama
DatagramPacket sendPacket =
para enviar ao cliente new DatagramPacket(sendData, sendData.length, IPAddress,
port);
Escreve o
datagrama para serverSocket.send(sendPacket);
dentro do socket }
}
}
Termina o loop while,
retorna e espera por
outro datagrama
Prof. Dr. Ricardo Couto Antunes da Rocha - Depto. de Ciência da Computação – Regional de Catalão 24