Documente Academic
Documente Profesional
Documente Cultură
Sockets
Programao de Sistemas
Sockets : 1/70
Utilizador
Aplicao Transporte Rede Ligao
Leornard Kleinrock, chefe do laboratrio da UCLA que desenvolveu e instalou primeiro encaminhador da ARPANET. Primeira mensagem enviada da UCLA para SRI/Stanford em Setembro 1969. Sockets : 2/70
Meio fsico
Programao de Sistemas
Programao de Sistemas
TCP-Transmission Control Protocol, de transferncia fivel e ordenada de uma sequncia de dados de qualquer dimenso. UDP-User Datagram Protocol, de transferncia no fivel de datagramas (bloco formatado de dados, com comprimento mximo). Nota1: Arpanet tinha em vista garantir em caso de guerra a transmisso de mensagens mesmo que alguns ns intermdios fossem eliminados. Nota2: protocolos TCP/IP definidos por Robert Kahn e Vinton Cerf. Programao de Sistemas Sockets : 4/70
Programao de Sistemas
Endereamento de ns (1)
No protocolo IP, cada n possui um endereo nico. O formato dos endereos depende da verso (IPv4 ou IPv6)
Endereamento de ns (2)
Curiosidade, para avaliao avanada apenas
c. Gama de endereos: representados segundo a representao CIDR- Classless Internet Domain Routing na forma base/mscara. A base o endereo inicial da gama e a mscara (netmask) determina os bits fixos no prefixo, nas formas:
Completa, indicando o valor de todos os grupos de 8 bits (entre 0 e 255) Curta, com o nmero de bits fixos.
Filtro curto
/24 /25 /26 /27 /28 /29 /30
Mscara
255.255.255.0 255.255.255.128 255.255.255.192 255.255.255.224 255.255.255.240 255.255.255.248 255.255.255.252
Nmero de endereos
256 128 64 32 16 8 4
Programao de Sistemas
Sockets : 7/70
Endereamento de ns (3)
Curiosidade, para avaliao avanada apenas
Ex: 193.136.143.0/24 indica prefixo de 24 bits, podendo variar os 32-24=8 bits menos significativos: assim coberta a gama 193.136.143.0 a 193.136.143.255 Ex: 193.136.143.120/29, podem variar 3 bits menos significativos: assim coberta a gama 193.136.143.120 a 193.136.143.127
Endereamento de ns (4)
Curiosidade, para avaliao avanada apenas
Endereamento de ns (5)
Curiosidade, para avaliao avanada apenas
Nota 1: as pilha de protocolos IPv4 e IPv6 so incompatveis. Nota 2: IPv6 foi disponibilizado no ncleo do Linux 2.6.10. Programao de Sistemas
Sockets : 10/70
A distribuio dos Bytes de nmeros de grande dimenso pode ser feita de duas formas1:
Big-endian: endereos mais baixos com ndices superiores (ex: MC68000). Little-endian: endereos mais baixos com ndices inferiores (ex: Intel x86).
Ex: seja o inteiro 1025 (0x00000401), a representar numa mquina de 32-bits a partir do endereo base 0x10000.
0x10003 0x10002 0x10001 0x10000
1
01 04 00 00
00 00 04 01
Big-endian
Little-endian
Sockets : 11/70
Programao de Sistemas
termos recolhidos da novela Viagens de Gulliver, de Jonathan Swift, sobre os lados favoritos de quebrar em Lilliput os ovos cozidos.
Portos (1)
O socket disponibiliza uma interface de envio/recepo de dados atravs de um porto. Cada tipo de socket pode ser ligado a 64K portos.
Os primeiros 1K portos (1-1023) so reservados pelo IANA para servios especficos, listados no ficheiro /etc/services, com privilgios de root:
22 : SSH 53 : DNS 80 : WWW 115 : FTP seguro 443 : WWW seguro
Os portos 49152-65535 so de evitar, por serem usados dinamicamente pelos sistemas operativos.
Programao de Sistemas Sockets : 14/70
Portos (2)
Aplicaes
Referncia a descritor
SSH
WWW
(protocolo HTTP)
socket
Sockets ligados (bound) a portos
socket
22
80
65535
Nota: Aplicaes podem usar mais do que um socket Sockets podem ser acedidas por vrias aplicaes
Programao de Sistemas
Sockets : 15/70
A principal diferena entre E/S de sockets e a E/S de ficheiros a forma como a aplicao abre os descritores de sockets.
Programao de Sistemas Sockets : 16/70
Valor
0 1 2 10
Descrio
No especificado Espao de nomes Unix (tubos e ficheiros) Internet IPv4 Internet IPv6 Sockets : 18/70
A API socket define no cabealho <sys/socket.h> uma estrutura genrica para endereos de todos os domnios.
struct sockaddr { sa_family_t sa_family; char sa_data[14]; };
Programao de Sistemas
Transcrio de endereo entre notao binria e cadeia de caracteres em notao ponto decimal efectuada por funes
POSIX: #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> char *inet_ntop(int,void *,char *,socklen_t); int inet_pton(int, char *, void *);
O 1 parmetro identifica a famlia. O 2 parmetro referencia a localizao fonte (endereo a transcrever). O 3 parmetro referencia a localizao destino O 4 parmetro socklen_t indica espao (INET_ADDRSTLEN para famlia AF_NET e INET6_ADDRSTLEN para famlia AF_NET6) Sockets : 20/70
Programao de Sistemas
Valor
1 2 3 10
Caracterstica da comunicao
Fluxo fivel de dados Orientado ao servio Entrega directamente datagrama ao protocolo de rede Igual a SOCK_STREAM, mas orientado mensagem
Programao de Sistemas
Sockets : 21/70
SOCK_DGRAM
Entrega no fivel (pacotes podem ser perdidos ou alterados) No h garantia de ordem na chegada Ligao inexistente (aplicao define destino para cada pacote) Pode enviar ou receber
Aplic.
3 2 1
Aplic.
socket
D1
socket
Dest.
3 2 1
D2 D3
Programao de Sistemas
Sockets : 22/70
Sensvel perda de dados? Largura de banda Restries de tempo? No No No 100 ms Sim Sim e no
Programao de Sistemas
Sockets : 23/70
A. Para se obter o endereo IP a partir do nome do n e o nmero de porto a partir do nome do servio, usar a funo
POSIX: #include <sys/socket.h> #include <netdb.h> int getaddrinfo(char *, char *, struct addrinfo *, struct addrinfo **);
Programao de Sistemas
O 1 parmetro referencia localizao do nome do n. O 2 parmetro referencia localizao do nome do servio. O 3 parmetro critrio de filtragem de endereos. O 4 parmetro indica endereo para onde inserida a resposta, numa lista.
Sockets : 24/70
Para filtragem nula, os campos int devem ter valor 0 e os ponteiros devem ser NULL.
Sockets : 25/70
Programao de Sistemas
Mensagem explicativa de erro no dada por perror(int), mas #include <netdb.h> char *gai_strerror(int); O campo ai_flags determina a forma de processar os nomes e endereos AI_ADDRCONFIG: Interrogar para qualquer tipo de endereo
configurado (IPv4 ou IPv6). AI_CANONNAME: Requere nome cannico. AI_NUMERICHOST: Endereo do n em formato numrico. AI_NUMERICSERV: Servio retornado como porto numrico. AI_V4MAPPED: Se o endereo tiver formato IPv4, mape-lo para formato IPv6. Sockets : 26/70
Programao de Sistemas
C.
Programao de Sistemas
Sockets : 27/70
#include <netdb.h> #include <arpa/inet.h> void print_protocol(struct addrinfo *aip) { printf(" protocol "); switch (aip->ai_protocol) { case 0: printf("default"); break; case IPPROTO_TCP: printf("TCP"); break; case IPPROTO_UDP: printf("UDP"); break; case IPPROTO_RAW: printf("raw"); break; default: printf("unknown (%d)", aip->ai_protocol); } }
Programao de Sistemas
Sockets : 28/70
Programao de Sistemas
Sockets : 29/70
Programao de Sistemas
Sockets : 30/70
Programao de Sistemas
Sockets : 31/70
Protocolo
O protocolo de nvel transporte adoptado na comunicao determinado pelo par (domnio,tipo)
Tipo Domnio
AF_UNIX SIM SIM AF_INET TCP UDP IP AF_UNSPEC SPP IDP SIM SPP
Programao de Sistemas
Sockets : 32/70
APUE 16.2
Ncleo
Hardware
Sockets : 34/70
APUE 16.3.4
O 1 parmetro identifica o descritor do socket. O 2 parmetro referencia a estrutura contendo o endereo IP. O 3 parmetro identifica a dimenso da estrutura contendo o endereo IP. O valor retornado 0(-1) em caso de sucesso (erro). Nota: ligao a portos at 1024 necessita privilgios de root.
Programao de Sistemas Sockets : 35/70
Programao de Sistemas
Sockets : 37/70
Programao de Sistemas
Sockets : 38/70
O 1 parmetro identifica o descritor do socket. O 2 parmetro identifica o endereo do servidor. O 3 parmetro identifica a dimenso da estrutura contendo o endereo IP.
Programao de Sistemas Sockets : 39/70
Em caso de insucesso deve haver um intervalo de espera at ser formulado novo pedido de ligao
#define MAXSLEEP 128 int nsec; for( nsec=1; nsec<=MAXSLEEP; nsec<<1 ) if( connect(socketfd,addr,len)==0 ) {
/* ligao aceite */
} sleep(nsec); }
Programao de Sistemas
Sockets : 40/70
Programao de Sistemas
Sockets : 41/70
POSIX:
#include <sys/types.h> #include <sys/socket.h> ssize_t send(int, char *, int, int); ssize_t recv(int, char *, int, int);
O 1 parmetro o descritor de ficheiro. O 2 parmetro o endereo dos dados de utilizador O 3 parmetro o nmero de Bytes a comunicar. O 4 parmetro identifica opes, normalmente 0. A funo devolve o nmero de Bytes efectivamente transferidos. Em caso de erro, o valor devolvido -1 e a causa do erro afixada na varivel errno. Nota 1: podem ser usadas as funes read() e write() Nota 2: as funes send e recv so bloqueantes. Programao de Sistemas Sockets : 43/70
CcL:Exemplo (1)
Pretende-se ligar dois ns por sockets segundo o modelo cliente-servidor. O protocolo de rede o TCP.
O programa do servidor recebe como parmetro na linha de comando o porto do socket. O servidor deve ser lanado primeiro. O programa do cliente recebe comos parmetros da linha de comando o endereo do n do servidor e o porto do socket.
Programao de Sistemas
Sockets : 44/70
CcL:Exemplo (2)
Cdigo comum nos programas do servidor e do cliente
#include #include #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <string.h> <strings.h> <unistd.h> <sys/types.h> <sys/socket.h> <netinet/in.h> <netdb.h>
Programao de Sistemas
Sockets : 45/70
CcL:Exemplo (3)
Cdigo do servidor
int main(int argc, char *argv[]) { int sockfd, newsockfd, clilen; char buffer[DIM]; struct sockaddr_in serv_addr,cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } /* cria socket */ sockfd=socket(AF_INET,SOCK_STREAM,0); if (sockfd<0) error("ERROR opening socket");
Programao de Sistemas
Sockets : 46/70
CcL:Exemplo (4)
/* socket associado ao porto*/ bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons( atoi(argv[1]) ); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); /* socket fica espera da requisio de uma ligao */ listen(sockfd,5); /* socket aceita ligao com o cliente */ clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept");
Programao de Sistemas
Sockets : 47/70
CcL:Exemplo (5)
/* socket l a mensagem do cliente, que impressa no terminal */ bzero(buffer,DIM); n = read(newsockfd,buffer,DIM); if (n < 0) error("ERROR reading from socket"); printf("Here is the message: %s\n",buffer); /* socket responde ao cliente */ n = write(newsockfd,"I got your message",18); if (n < 0) error("ERROR writing to socket"); /* socket fechado */ close(newsockfd); return 0;}
Programao de Sistemas
Sockets : 48/70
CcL:Exemplo (6)
Cdigo do cliente
int main(int argc, char *argv[]) { int sockfd, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[DIM]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n",argv[0]); exit(0); } /* cria socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket");
Programao de Sistemas
Sockets : 49/70
CcL:Exemplo (7)
Cdigo do cliente
server = gethostbyname(argv[1]); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } /* solicita a ligao ao servidor */ bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons( atoi(argv[2]) ); if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting");
Programao de Sistemas
Sockets : 50/70
CcL:Exemplo (8)
Cdigo do cliente
/* recolhe mensagem */ printf("Please enter the message: "); bzero(buffer,DIM); fgets(buffer,DIM-1,stdin); /* envia mensagem para o servidor */ n = write(sockfd,buffer,strlen(buffer)); if (n < 0) error("ERROR writing to socket"); bzero(buffer,DIM); /* recolhe resposta do servidor e imprime-a no terminal */ n = read(sockfd,buffer,DIM-1); if (n < 0) error("ERROR reading from socket"); printf("%s\n",buffer); close(sockfd); return 0;}
Programao de Sistemas
Sockets : 51/70
CcL:Exemplo (9)
Sesso no n servidor
[rgc@asterix Cliente-servidor]$ server 26000 Here is the message: Greetings from Canada! [rgc@asterix Cliente-servidor]$
Sesso no n cliente
[rgc@ottawa ~]$ client 193.136.143.1 26000 Please enter the message: Greetings from Canada! I got your message [rgc@ottawa ~]$
Programao de Sistemas
Sockets : 52/70
Programao de Sistemas
Sockets : 53/70
Programao de Sistemas
Sockets : 54/70
Programao de Sistemas
Sockets : 55/70
A funo
Fecha a ligao para SOCK_STREAM. Liberta o porto usado pelo socket.
Programao de Sistemas
Sockets : 56/70
Programao de Sistemas
Sockets : 57/70
APUE 14.5.1
Muitas das chamadas da API sockets so bloqueantes: quando o processo chama uma funo bloqueante, ele fica suspenso espera do evento.
accept: espera que o pedido de ligao chegue. connect: espera que o pedido de ligao seja estabelecida. recv,recvfrom: espera que o pacote de dados seja recebido. send,sendto: espera que os dados sejam transferidos para a memria tampo (buffer) do socket. Nota: este bloqueio no depende da rede, mas provoca atraso no processo.
Para aplicaes simples, o bloqueio benfico (ex: evita consumo de tempo de CPU).
Sockets : 58/70
Programao de Sistemas
Programao de Sistemas
O 1 parmetro identifica o cdigo do maior descritor de socket + 1. O 2 parmetro referencia lista de descritores de leitura. O 3 parmetro referencia lista de descritores de escrita. O 4 parmetro referencia lista de descritores para verificar se ocorreu uma excepo. O 5 parmetro determina o intervalo de retorno, caso nada tenha ocorrido (NULL para intervalo infinito). A funo devolve o nmero de descriptores afectados por sinais. Em caso de erro, o valor devolvido -1.
Os descriptores de sockets so referenciados numa tabela de bits, de tipo struct fd_set. Para acesso foram criadas vrias funes:
void FD_ZERO(fd_set *); /* torna estrutura nula */ void FD_CLR(int, fd_set *); /* coloca bit a 0 */ void FD_SET(int, fd_set *); /* coloca bit a 1 */ int FD_ISSET(int, fd_set *); /* devolve valor do bit */
O socket de descriptor i est pronto para leitura / escrita / excepo se o bit estiver a 1 nos parmetros nmero 2(readfds), 3(writefds) ou 4(exceptfds).
Se, ao fim de 5 segundos nada for recebido, o servidor deve afixar uma mensagem de aviso no terminal.
Programao de Sistemas
Sockets : 62/70
Cdigo do servidor
#include #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <strings.h> <netinet/in.h> <sys/time.h> <sys/socket.h> <sys/types.h> <unistd.h>
Programao de Sistemas
Sockets : 63/70
Programao de Sistemas
Sockets : 64/70
Programao de Sistemas
Sockets : 65/70
Programao de Sistemas
Sockets : 66/70
Cdigo do cliente
#include <stdio.h> #include <stdlib.h> #include <strings.h> #include <netinet/in.h> #define LEN 80 void error(char *msg) { perror(msg); exit(1); } int main(int argc, char **argv) { int sockfd; struct sockaddr_in serv_addr; char buf[LEN]; int len,nbytes;
Programao de Sistemas
Sockets : 67/70
Programao de Sistemas
Sockets : 68/70
Programao de Sistemas
Sockets : 69/70
Programao de Sistemas
Sockets : 70/70