View
217
Download
1
Category
Preview:
Citation preview
2: Application Layer 1
Capítulo 2: Camada de Aplicação 2.1 Princípios da
camada de aplicação 2.2 Web e HTTP 2.3 FTP 2.4 Email
SMTP, POP3, IMAP 2.5 DNS
2.6 Aplicações P2P 2.7 Programação de
socket usando TCP 2.8 Programação de
socket usando UDP
2: Application Layer 2
Programação com Sockets
Socket API Introduzida no BSD4.1
UNIX, 1981 Paradigma cliente/servidor Dois tipos de serviço na
camada de transporte via socket API: Datagrama não
confiável Stream de bytes
“confiável”
Interface (porta) local, criada pela aplicação,
controloda pelo SO pela qual um processo pode
enviar e receber mensagens para/de
outro processo (aplicação)
socket
2: Application Layer 3
Programação de Sockets usando TCPSocket: porta entre a aplicação e o protocolo de transporte (UCP ou TCP)Serviço do TCP service: transferência confiável de bytes entre dois processos
process
TCP withbuffers,
variables
socket
controlled byapplicationdeveloper
controlled byoperating
system
host orserver
process
TCP withbuffers,
variables
socket
controlled byapplicationdevelopercontrolled byoperatingsystem
host orserver
internet
2: Application Layer 4
Socket - TCPCliente deve contactar o
servidor Processo servidor já em
execução Servidor cria o socket
reponsável pelas boas-vindas ao cliente
Cliente contacta o servidor através:
Da criação do socket TCP local
Especificando o endereço IP e o número da porta do processo servidor
Quando o cliente cria o socket: cliente TCP estabelece uma conexão com o servidor TCP
Quando contactado pelo cliente, servidor TCP cria um novo socket para o processo servidor se comunicar com o cliente Permite o servidor
‘conversar’ com vários clientes
Número da porta para distinguir os clientes (Cap 3)
TCP provê confiabilidadee transferência de bytes
em ordem (“pipe”)
Do ponto de vista da aplicação
2: Application Layer 5
Interação Cliente/servidor: TCP
close ()
listen ()
bind ()
socket ()
accept ()
read ()
w rite ()
socket ()C lien te
connect ()bloqueado Es ta b e lec im en to d e con ex ão
w rite ()
read ()
close ()
D ad os (p ed id o )
D ad os resp osta )
2: Application Layer 6ou
tToS
erve
r
to network from network
inFr
omS
erve
r
inFr
omU
ser
keyboard monitor
Process
clientSocket
inputstream
inputstream
outputstream
TCPsocket
Clientprocess
client TCP socket
Fluxo de Dados Um fluxo é uma
sequência de caracters que é enviado ou recebido por um processo
Um fluxo de entrada é ligado a alguma fonte de entrada do processo e.g., teclado ou socket.
Um fluxo de saída é ligado a alguma uma saída do processo, e.g., monitor ou socket.
2: Application Layer 7
Capítulo 2: Camada de Aplicação 2.1 Princípios da
camada de aplicação 2.2 Web e HTTP 2.3 FTP 2.4 Email
SMTP, POP3, IMAP 2.5 DNS
2.6 Aplicações P2P 2.7 Programação de
socket usando TCP 2.8 Programação de
socket usando UDP
2: Application Layer 8
Socket - UDP
UDP: não existe “conexão” entre o cliente e o servidor
Não é realizado o handshaking
Remetente deve explicitamente anexar o endereço IP e a porta de destino em cada pacote
Servidor deve extrair o endereço IP e a porta do remente de cada pacote recebido
UDP: dados transmitidos podem ser recebidos for a de ordem ou perdidos
Do ponto de vista da aplicação
UDP provê uma tranferência não confiável
de um grupo de bytes (“datagramas”)
2: Application Layer 9
Interação Cliente/servidor: UDP
sendto ()
bind ()
socket ()
recvfrom ()
S ervid or
socket ()C lien te
bloqueado
sendto ()
recvfrom ()
D ad os (p ed id o )
D ad os resp osta )
close ()close ()
2: Application Layer 10
Sockets de Berkeley Os "sockets" de Berkeley são uma API genérica
para programação sobre protocolos de comunicação
A implementação das system-calls desta interface é padrão em todos os sistemas operacionais UNIX
Descritores são números inteiros usados para facilitar o acesso ao controle das comunicações e são conhecidos por "sockets".
Estrutura especial (independente do protocolo): struct sockaddr { u_short sa_family; char sa_data[14]; };
2: Application Layer 11
Sockets de Berkeley Para cada família de protocolos existem estruturas
específicasstruct in_addr
{ u_long s_addr; /* endereço IP (4 bytes) */ };
struct sockaddr_in { short sin_family; u_short sin_port; /* porta (2 bytes) */ struct in_addr sin_addr; char sin_zero[8]; };
2: Application Layer 12
Abertura de Sockets Para ter acesso aos protocolos de comunicação
cria-se um socket, utilizando a "system-call" "socket" que devolve um descritor necessário em todas as operações subsequentes.
int socket(int family, int type, int protocol);
Family Type Protocol ProtocolAF_INET SOCK_DGR
AM IPPROTO_UDP UDP
AF_INET SOCK_STREAM
IPPROTO_TCP TCP
AF_INET SOCK_RAW IPPROTO_ICMP ICMP AF_INET SOCK_RAW IPPROTO_RAW IP
2: Application Layer 13
Associando endereços a Sockets
Antes de receber ou enviar dados através de um descritor aberto, é necessário definir a porta que vai ser usada por esse descritor. Assim, deve ser utilizada a "system-call" bind:
int bind(int sock, struct sockaddr *myAddress, int addrLen);
O parâmetro sock é o descritor devolvido anteriormente pela função socket, o segundo parâmetro é um ponteiro para a estrutura que contém o endereço e o último parâmetro é o tamanho dessa estrutura.
2: Application Layer 14
Associando endereços a Sockets
struct sockaddr_in myAddr;int sock=socket(AF_INET,SOCK_DGRAM,0);bzero((char *)&myAddr,sizeof(myAddr));myAddr.sin_family=AF_INET myAddr.sin_addr.s_addr=htonl(INADDR_ANY);myAddr.sin_port=htons(6520);
if(-1==bind(sock, (struct sockaddr *)&myAddr, sizeof(myAddr))) { puts("Porta ocupada"); close(sock); exit(1); }
O valor INADDR_ANY representa o endereço IP da máquina onde a aplicação é executada.
No exemplo utiliza-se a porta 6520, se o "socket" for usado para recepção de dados o emissor terá de os enviar para esta porta.
A função bzero é usada para colocar zeros na estrutura myAddr.
Funções htonl e htons permitem a conversão de números inteiros longos e curtos do formato interno da máquina ("host") para o formato usado na rede ("net"). As funções ntohl e ntohs, não usadas neste exemplo, realizam a operação inversa.
2: Application Layer 15
Emissão e Recepção de Datagramas UDP
As "system-calls" mais importantes para a emissão e recepção de "datagramas" UDP são sendto e recvfrom:
int sendto(int sock, char *buffer, int buffSize, int flags, struct sockaddr *to, int addrLen);
int recvfrom(int sock, char *buffer, int buffSize, int flags, struct sockaddr *from, int *addrLen);
O parâmetro sock é o descritor a ser usado para o envio ou recepção dos datagramas, buffer e buffSize definem onde estão os dados a enviar, ou onde devem ser colocados os dados a receber. O parâmetro flags permite usar algumas opções que alteram alguns aspectos do modo de funcionamento destas "system-calls", normalmente terá o valor zero.
A estrutura to contém o endereço de destino para o "datagrama" a ser emitido, a estrutura from é usada para guardar o endereço de proveniência de um "datagrama" recebido.
2: Application Layer 16
Exemplo – Enviando datagramas UDP
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>void main(void){ struct sockaddr_in me, target; int sock=socket(AF_INET,SOCK_DGRAM,0); char linha[81]; bzero((char *)&me,sizeof(me)); me.sin_family=AF_INET; me.sin_addr.s_addr=htonl(INADDR_ANY); /* endereço IP local */ me.sin_port=htons(0); /* porta local (0=auto assign) */ bind(sock,(struct sockaddr *)&me,sizeof(me)); bzero((char *)&target,sizeof(target)); target.sin_family=AF_INET; /* endereço IP de destino */ target.sin_addr.s_addr=inet_addr("193.136.62.4"); target.sin_port=htons(8450); /* porta de destino */ do { gets(linha); sendto(sock,linha,81,0,(struct sockaddr *)&target, sizeof(target)); } while(strcmp(linha,"exit")); close(sock);}
2: Application Layer 17
Exemplo – Recebendo datagramas UDP
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>void main(void){struct sockaddr_in from, me;int sock, addrlen=sizeof(me);char linha[81];sock=socket(AF_INET,SOCK_DGRAM,0);bzero((char *)&me,addrlen);me.sin_family=AF_INET;me.sin_addr.s_addr=htonl(INADDR_ANY);me.sin_port=htons(8450);bind(sock,(struct sockaddr *)&me,addrlen);do { recvfrom(sock,linha,81,0,(struct sockaddr *)&from, &addrlen); puts(linha); }while(strcmp(linha,"exit"));close(sock);}
2: Application Layer 18
Típico Cliente UDP
Cria um socket UDP Cria a estrutura sockaddr com o endereço do
servidor Chama a função sendto() , enviando a
requisição ao servidor. Não é necessária a função bind()
Possivelmente chama a função recvfrom(), caso necessite de uma resposta
2: Application Layer 19
Típico Servidor UDP
Cria um socket UDP e chama a função bind() Chama a função recvfrom () , para receber
requisições A função sendto() é usada para enviar as
respostas ao cliente
2: Application Layer 20
Conexão TCP
O estabelecimento da conexão garante a existência de um canal bidirecional dedicado de transferência de "bytes".
O protocolo TCP proporciona serviços orientados à conexão. Antes de ser possível enviar ou receber dados há necessidade de se estabelecer a conexão.
O estabelecimento da conexão exige a colaboração entre as duas aplicações, uma aplicação escuta pedidos de conexão numa dada porta, enquanto a outra emite um pedido de conexão para essa porta
int listen(int sock, int backlog); Esta "system-call" permite colocar um "socket" em escuta de
pedidos de conexões numa dada porta. A porta deverá ter sido previamente definida com a "system-call" bind.
Processo fica suspenso até que chegue um pedido de conexão, a menos que um pedido já tenha sido recebido desde a invocação de listen.
2: Application Layer 21
Conexão TCP
O valor backlog define o número de pedidos de conexão que podem ser mantidos em espera sem serem aceites pela "system-call" accept.
int accept(int sock, struct sockaddr *from, int *addrLen); A "system-call" accept permite aceitar um pedido de conexão,
devolve um novo "socket" já ligado ao emissor do pedido e o "socket" original mantém-se em escuta. A estrutura from é usada para guardar o endereço de proveniência do pedido de conexão.
A "system-call" accept é bloqueante, quando é invocada o processo fica suspenso até que chegue um pedido de conexão, a menos que um pedido já tenha sido recebido desde a invocação de listen.
O conceito de conexão implica que o "socket" devolvido por accept seja totalmente independente do "socket" original. Enquanto o "socket" original continua à escuta de novos pedidos de conexão, o novo "socket" está associado a uma conexão entre duas aplicações e portanto permite a circulação de dados exclusivamente entre essas duas aplicações
2: Application Layer 22
Conexão TCP
A aplicação que toma a iniciativa de estabelecer uma conexão utiliza a "system call" connect:
int connect(int sock,struct sockaddr *address, int addressLen) O "socket" sock deverá ser do tipo apropriado
("SOCK_STREAM") e não necessita ser atribuída uma porta ("bind"). Esta "system-call" encarrega-se de a definir dinamicamente.
A estrutura address deverá conter o endereço de destino no qual uma aplicação espera por novas conexões
2: Application Layer 23
Emissão e Recepção - TCP
Uma vez estabelecida a conexão passa a existir um canal dedicado para comunicação entre os dois hosts e que não está acessível a terceiros.
O endereço de destino já está definido e podem ser utilizadas as "system-call" read e write, respectivamente para receber e enviar dados:
int read(int sock, char *buffer, int len); int write(int sock, char *buffer, int len);
A "system-call" read recebe len bytes, do "socket" sock, colocando-os no buffer. A "system-call" write envia len " bytes "do buffer pelo "socket" sock.
A utilização destas "system-call" deve ser cuidadosa: ambas devolvem o número de" bytes "recebidos ou emitidos que podem não coincidir com o parâmetro len.
Por outro lado, tal como recvfrom, a "system-call" read bloqueia até que sejam recebidos os dados, isto quer dizer que se a invocarmos para receber 1000" bytes "de uma conexão, podemos ter de esperar até que essa quantidade de informação chegue. Note-se que a "system-call" recvfrom desbloquea quando chega um "datagrama" UDP de qualquer tamanho.
2: Application Layer 24
Exemplo– Estabelecendo conexão TCP
struct sockaddr_in target;int sock;char linha[81];sock=socket(AF_INET,SOCK_STREAM,0);bzero((char *)&target,sizeof(me));target.sin_family=AF_INET;target.sin_addr.s_addr=inet_addr("193.136.62.4");target.sin_port=htons(8451);connect(sock,(struct sockaddr *)&target,sizeof(target));do { gets(linha); write(sock,linha,81); }while(strcmp(linha,"exit"));close(sock);
2: Application Layer 25
Exemplo– Recebendo dados via TCP
struct sockaddr_in from, me;int newSock,sock, addrlen=sizeof(from);char linha[81];sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);bzero((char *)&me,addrlen);me.sin_family=AF_INET;me.sin_addr.s_addr=htonl(INADDR_ANY);me.sin_port=htons(8451);bind(sock,(struct sockaddr *)&me,addrlen);listen(sock,5);newSock=accept(sock,(struct sockaddr *)&from,&addrlen);close(sock);do{ read(newSock,linha,81); puts(linha);}while(strcmp(linha,"exit"));close(newSock);
2: Application Layer 26
Recebendo dados via TCP
O "socket" usado para receber o pedido de conexão não serve para troca de dados e neste exemplo é fechado após o estabelecimento da conexão. O novo "socket", associado à conexão é depois usado para recepção de dados.
Quando um "socket" TCP é definido como não bloqueante, as consequências são as seguintes:
Sempre que uma operação falha por não existir a possibilidade de execução sem bloqueio a "system- call" devolve -1.
connect: ao contrário do que acontece com "sockets" UDP, com "sockets" TCP, esta "system-call" bloqueia a execução até que a conexão esteja estabelecida. Se o "socket" é não bloqueante devolve imediatamente o valor -1
accept: se existe algum pedido devolve o novo "socket", caso contrário gera um erro.
read: efetua leituras parciais, o total de" bytes "lidos é devolvido pela "system-call"
write: efetua escritas parciais, tal como para a anterior devolve o número de" bytes "processados.
Sessão típica - TCP
2: Application Layer 28
Resolução de Nomes
Para resolver o nome de uma máquina pode ser utilizada a função gethostbyname:
hostent *gethostbyname(char *hostName); Esta função devolve um ponteiro para uma
estrutura do tipo hostent, o campo h_addr_list, é um ponteiro para um vetor que contem os vários endereços IP da máquina cujo nome foi passado como parâmetro. Na prática, a menos que se trate de um roteador, cada máquina apenas tem um endereço IP pelo que se usa o primeiro elemento do vetor.
Os endereços IP guardados no vetor estão sob a forma de inteiros longos, já em formato de rede pelo que podem ser diretamente copiados para o campo sin_addr das estruturas sockaddr_in.
2: Application Layer 29
Recepção Assíncrona
Recepção assíncrona: recepção de dados por uma aplicação sem bloqueio da mesma. Independentemente das chegadas de dados a aplicação deve continuar funcionando normalmente.
A recepção assíncrona é necessária se a aplicação recebe dados em diferentes portas, ou se mesmo recebendo em apenas numa porta, executa outras tarefas e não pode ficar suspensa à espera que os dados cheguem.
Um dos métodos possíveis é definir o "socket" como não bloqueante, nesse caso a aplicação deverá invocar periodicamente as "system-call" recvfrom ou read para verificar se chegaram dados ("polling").
2: Application Layer 30
Recepção Assíncrona
Outros métodos: Sinais - O processo recebe um sinal sempre que chegam dados.
Os sinais são processados por funções definidas na aplicação. Quando o sinal chega ao processo a sua execução é suspensa enquanto a referida função é executada. A função de processamento do sinal pode receber diretamente os dados ou simplesmente alterar uma variável global que assinala a chegada de dados.
Threads - Unidades de execução sequencial que são executadas concorrentemente dentro do mesmo processo. Pode-se colocar um "thread" à espera da chegada de dados enquanto os restantes continuam a sua execução normal.
"System-call" select - esta é uma solução parcial, permite escutar dados em mais do que uma porta, o processo fica bloqueado, mas quando chegam dados a uma das portas o processo é desbloqueado.
Principais Funçõesso c k e t C ria um novo descrito r para com unicação
co n n e c t In iciar conexão com serv idor
w r ite Escreve dados em u m a conex ão
re a d Lê dados de u m a conexão
c lo s e F echa a conexão
b in d Atribu i um endereço IP e um a porta a um socket
l is te n C oloca o socket em m odo passivo , para “escu tar” portas
a c c e p t B loqueia o serv idor até chegada de requ isição de conexão
re c v fr o m R ecebe um datagram a e guarda o endereço do em issor
s e n d to Envia um datagram a especificando o endereço
2: Application Layer 32
Resumo: Capítulo 2
Arquitetura das aplicações cliente-servidor P2P híbrida
Serviços requeridos pela aplicação: confiabilidade, banda,
atraso Modelos de serviço da camada
de transporte Orientado a conexão,
confiável: TCP Não confiável, datagramas:
UDP
Protocolos específicos: HTTP FTP SMTP, POP, IMAP DNS P2P: BitTorrent, Skype
Programação em sockets
2: Application Layer 33
Resumo: Capítulo 2
Mensagens de requisição/resposta: Cliente requisita
informações ou serviços
Servidor responde com dados e código de status
Formato das mensagens: cabeçalho: campos
dando informação sobre os dados
dado: info sendo enviada
Sobre protocolosImportante : controle vs. msgs
dados in-band, out-of-
band centralizado vs.
descentralizado Sem estado vs. com
estado Transferência
Confiável vs. não confiável
Recommended