2: Application Layer 1 Capítulo 2: Camada de Aplicação 2.1 Princípios da camada de aplicação ...

Post on 07-Apr-2016

216 views 1 download

Transcript of 2: Application Layer 1 Capítulo 2: Camada de Aplicação 2.1 Princípios da camada de aplicação ...

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