Sunteți pe pagina 1din 35

Programao de Sistemas

Sockets

Programao de Sistemas

Sockets : 1/70

Introduo Internet (1)


O modelo de comunicao mais divulgado em redes de computadores a Internet
Baseada numa pilha de protocolos com 4 nveis,
nveis mais elevados so mais abstractos e mais prximos do utilizador nveis mais baixos so prximos das transferncias de bits entre computadores.

Cada nvel usa os servios oferecidos pelo nvel imediatamente inferior.

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

Introduo Internet (2)


4. Nvel aplicao (application): contm as aplicaes teis para os utilizadores.
Objectivos: converter dados na representao local para representao cannica e implementar modelo de comunicao. Exemplos de aplicaes muito divulgadas:
WWW (World Wide Web), baseado no protocolo HTTPHypertext Transfer Protocol. Correio electrnico (Email-Electronic Mail), baseado no protocolo SMTP-Simple Mail Transfer Protocol. Transferncia de ficheiros, baseado no protocolo FTP-File Transfer Protocol. DNS (Domain Name Service): transcrio de nomes lgicos (nomes definidos numa hierarquia em rvore) para endereos de ns da rede. Sockets : 3/70

Programao de Sistemas

Introduo Internet (3)


3. Nvel transporte (transport):
Objectivos: transferir todos os dados ponto a ponto (ns da rede de computadores, que podem no se encontrar directamente ligados entre si). Protocolos mais usados:

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

Introduo Internet (4)


2. Nvel rede (network):
Objectivos: encaminhamento de pacotes de uma rede para outra. Protocolos mais usados
IP-Internet Protocol IPSec, que permite estabelecer em cima do IP uma rede segura (com mecanismos de cifra e autenticao)

1. Nvel ligao (link):


Objectivos: encapsular bits em tramas (frame), com detector de erros de transmisso, e enviar as tramas de um computador para outro. Exemplos:
Ethernet, numa rede local, 802.11b, para Wi-Fi Wireless Fidelity Sockets : 5/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)

1. IPv4: actualmente em uso, norma rfc791 (1981)


a. Espao para endereo: 32 bits (4 Bytes), com limite terico de 4G ns. b. Representao de um endereo: notao mais usada a notao ponto-decimal, cada Byte indicado em decimal. Ex: o servidor da rea Cientfica de Computadores do DEEC tem endereo 193.136.143.1 Nota: para aumentar legibidade em 1983 foi criado o sistema DNS - Domain Name System para transcrever endereos IP para nomes lgicos na forma ID.domnio Ex: asterix.ist.utl.pt e comp.ist.utl.pt so nomes para o endereo 193.136.143.1
Programao de Sistemas Sockets : 6/70

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

d. Reserva de endereos: a IANA-Internet Assigned Numbers Authority reservou gamas de endereos


127.0.0.0/8 loopback 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 redes locais 255.255.255.255 difuso

e. Dimenso mxima do datagrama MTU (Maximum Transmission Unit) de 64KB-20B


Programao de Sistemas Sockets : 8/70

Endereamento de ns (4)
Curiosidade, para avaliao avanada apenas

Para prolongar a vida do espao de endereamento vrias tecnologias tm sido desenvolvidas:


Translaco de endereos (NAT-Network Address Translation) por uma Firewall entre a rede privada e local. Os endereos da rede interna so trocados pelo endereo externo da Firewall. Aluguer de endereos por servio DHCP-Dynamic Host Configuration Protocol
Usado quando um PC em casa se liga a um ISP-Internet Service Provider. Tempo de aluguer varia com o tipo de equipamento (ex: 2 dias para computador fixo e 1 hora para computador mvel) e pode ser estendido depois de gasto 50% do tempo de aluguer.

A procura de endereos IP provm de diversos factores:


Aumento de utilizadores de Internet. Popularidade de equipamentos mveis (portteis, PDAs, telemveis).

IANA prev para 2010 o esgotamento dos endereos IPv4.


Programao de Sistemas Sockets : 9/70

Endereamento de ns (5)
Curiosidade, para avaliao avanada apenas

2. IPv6: em fase de instalao, norma rfc2373 (1998)


a. Espao para endereo: 128 bits (16 Bytes), com limite terico de 3.4*1038 ns. b. Representao de um endereo: notao mais usada dado por 8 grupos de 4 dgitos hexadecimais, separados por dois pontos (:). Uma nica sub-sequncia de quatro 0s pode ser compactada por um par de dois pontos. Ex: 2001:0db8:0000:0000:0000:0000:1428:57ab e 2001:db8::1428:57ab so endereos IPv6.
[Exemplo] [rgc@asterix ~]$ host ipv6.l.google.com ipv6.l.google.com has IPv6 address 2001:4860:0:1001::68

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

Representao de Bytes (1)


Curiosidade, para avaliao avanada apenas

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

0x10003 0x10002 0x10001 0x10000

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.

Representao de Bytes (2)


Curiosidade, para avaliao avanada apenas

Vantagens da representao big-endien:


Inteiros armazenados na mesma ordem das cadeias de caracteres (da esquerda para a direita). Sinal do nmero determinado olhando para o Byte de endereo base.

Vantagens da representao little-endien:


Facilita converso de representaes com diferentes tamanhos (ex: inteiro 12 representado pelo Byte 0x0C e pela palavra 0x000C: a localizao de deslocamento mantm o mesmo valor, o que no acontecia na representao bi-endien).

Na rede Internet, os endereos so sempre representados em big-endien.


Nota: os primeiros ns encaminhadores (router) da rede ARPANET, designados Interface Message Processor, eram mquinas Honeywell DDP516 de 16 bits com representao big-endien. Programao de Sistemas Sockets : 12/70

Representao de Bytes (3)


Curiosidade, para avaliao avanada apenas

No API de sockets so sempre chamadas funes de converso da representao de inteiros :


Dimenses: 4 Bytes (long) e de 2 Bytes (short) Locais: n (host) e protocolo IP (network)
#include uint32_t uint16_t uint32_t uint16_t <arpa/inet.h> htonl(uint32_t); htons(uint16_t); ntohl(uint32_t); ntohs(uint16_t); /* 4B do n para rede */ /* 2B do n para rede */ /* 4B da rede para n */ /* 2B da rede para n */

Nota: se o processador tiver arquitectura big-endien, as funes no fazem nada.


Programao de Sistemas Sockets : 13/70

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

Interface rede (endereo 193.136.143.1)

Sockets : 15/70

Introduo aos sockets (1)


Os sockets, introduzidos em 1981 no BSD 4.1, definem os pontos de acesso das aplicaes segundo o paradigma cliente/servidor. Aplicao Socket
Protocolo A Protocolo B

... Programao de sockets mais complexa que E/S de ficheiros


mais parmetros mais chamadas de sistema

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

Introduo aos sockets (2)


Os processos lem e escrevem nos descritores de sockets pelas mesmas operaes read e write dos descritores de ficheiros. Servios disponibilizados pelos sockets [analogia]
A. socket() - definio [telefone] B. bind() associao do socket a um endereo [atribuir nmero ao telefone] C. listen() - escutar [destinatrio espera pelo toque da campanha] D. connect() - estabeler conexo [origem digita nmero do destinatrio] E. accept() - estabeler conexo [destinatrio aceita chamada, levantando o ascultador] F. send(),recv() - envio/recepo de dados [falar] G. close() - fecho de conexo [pousar ascultador] Programao de Sistemas Sockets : 17/70

Domnio de um socket (1)


O domnio do socket determina a natureza da comunicao, incluindo o formato dos endereos do ns de computadores. Os domnios, todos com prefixo AF_, so definidos no cabealho <bits/socket.h>, lido a partir do <sys/socket.h>
Domnio
AF_UNSPEC AF_UNIX AF_INET AF_INET6 Programao de Sistemas

Valor
0 1 2 10

Descrio
No especificado Espao de nomes Unix (tubos e ficheiros) Internet IPv4 Internet IPv6 Sockets : 18/70

Figura 16.1 Advanced Programming in the UNIX Environment

Domnio de um socket (2)


Curiosidade, para avaliao avanada apenas

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]; };

Para o domnio AF_INET, o cabealho <netinet/in.h> define a estrutura


struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; /* nmero de porto */ /* endereo IP */ /* no usado */

Para o domnio AF_INET6 usada a estrutura sockaddr_in6


Sockets : 19/70

Programao de Sistemas

Domnio de um socket (3)


Curiosidade, para avaliao avanada apenas

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

Tipo de socket (1)


O tipo de socket determina as caractersticas de comunicao. Os tipos , todos com prefixo SOCK_, so definidos no cabealho <bits/socket.h>, lido a partir do <sys/socket.h>
Tipo
SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET

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

Figura 16.2 Advanced Programming in the UNIX Environment

Programao de Sistemas

Sockets : 21/70

Tipo de socket (2)


SOCK_STREAM
Entrega fivel. Ordem garantida (1 a enviar o 1 a ser entregue,) Orientado ligao (todos os pacotes seguem depois de ter sido estabelecda a ligao) Bidireccional

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

Tipo de socket (3)


Curiosidade, para avaliao avanada apenas

A escolha do tipo depende da aplicao


Aplicao FTP Email WWW udio DNS Financeira Sim Sim Sim No No Sim Elstica Elstica Elstica 5 Kbps Baixa Elstica

Seleccionado tipo SOCK_STREAM

Sensvel perda de dados? Largura de banda Restries de tempo? No No No 100 ms Sim Sim e no

Seleccionado tipo SOCK_DGRAM Seleccionado tipo SOCK_DGRAM ou SOCK_STREAM

Programao de Sistemas

Sockets : 23/70

Obteno do endereo IP (1)


Curiosidade, para avaliao avanada apenas

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

Obteno do endereo IP (2)


Curiosidade, para avaliao avanada apenas

A estrutura addrinfo possui obrigatoriamente os seguintes campos:


struct addrinfo { int ai_flags; int ai_family; /* domnio */ int ai_socktype; /* tipo socket */ int ai_protocol; /* protocolo */ socklen_t ai_addrlen; /* comprimento endereo */ struct sockaddr *ai_addr; /* endereo */ char *ai_cannonname; /* nome n */ struct addrinfo *next; /* seguinte na lista */ };

Para filtragem nula, os campos int devem ter valor 0 e os ponteiros devem ser NULL.
Sockets : 25/70

Programao de Sistemas

Obteno do endereo IP (3)


Curiosidade, para avaliao avanada apenas

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

Obteno do endereo IP (4)


Curiosidade, para avaliao avanada apenas

B. Na biblioteca normalizada do C, usar


#include <netdb.h> struct hostent *gethostbyname(char *);
O parmetro pode ser dado em dot-notation ou nome.
/* Official name of host. */ /* Alias list. */ /* Host address type. */ /* Length of address. */ /* List of addresses from name server. */ /* Address, for backward compatibility. */ typedef struct { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; #define h_addr h_addr_list[0] } hostent ;

C.

No shell o endereo pode ser recolhido na forma host nome


[rgc@asterix ~]$ host ottawa.ist.utl.pt ottawa.ist.utl.pt has address 193.136.143.66

Programao de Sistemas

Sockets : 27/70

Exemplo de identificao (1)


Curiosidade, para avaliao avanada apenas

Consideremos um programa que lista o endereo de um n e o porto de um servio

#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

Exemplo de identificao (2)


Curiosidade, para avaliao avanada apenas
int main(int argc, char *argv[]) { struct addrinfo *ailist, *aip, hint; struct sockaddr_in *sinp; int err; const char *addr; char abuf[INET_ADDRSTRLEN]; if (argc != 3) { printf("usage: %s nodename service\n", argv[0]); exit(1); }

Programao de Sistemas

Sockets : 29/70

Exemplo de identificao (3)


Curiosidade, para avaliao avanada apenas
hint.ai_flags = AI_CANONNAME; hint.ai_family=hint.ai_socktype=hint.ai_protocol=hint.ai_addrlen=0; hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL; if ((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0) { printf("getaddrinfo error: %s", gai_strerror(err)); exit(1); } for (aip = ailist; aip != NULL; aip = aip->ai_next) { print_protocol(aip); printf("\n\thost %s", aip->ai_canonname?aip->ai_canonname:"-"); if (aip->ai_family == AF_INET) { sinp = (struct sockaddr_in *)aip->ai_addr; addr = inet_ntop(AF_INET,&sinp->sin_addr,abuf,INET_ADDRSTRLEN); printf(; address %s", addr?addr:"unknown"); printf(; port %d", ntohs(sinp->sin_port)); } printf("\n"); } exit(0); }

Programao de Sistemas

Sockets : 30/70

Exemplo de identificao (4)


[rgc@asterix List]$ list lect14.cs.ucdavis.edu ssh protocol TCP host lect14.cs.ucdavis.edu; address 169.237.5.137; port 22 protocol UDP host -; address 169.237.5.137; port 22 [rgc@asterix List]$

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

SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET

Server Information Manager Protocol

Internet Datagram Protocol

Sequenced Packet Protocol

Programao de Sistemas

Sockets : 32/70

APUE 16.2

Criao de um socket (1)


Um socket criado em C, pela chamada de sistema
POSIX: #include <sys/socket.h> int socket(int, int, int); O 1 parmetro identifica o domnio de comunicao. O 2 parmetro identifica o tipo de sockect. O 3 parmetro identifica o protocolo de transporte (cdigos afixados em /etc/protocols, normalmente usado 0-protocolo por omisso). O valor retornado o descritor do socket, ou -1 em caso de erro. Nota: a funo socket() no determina de onde os dados prevm os dados, nem para onde eles vo apenas cria a interface.
Programao de Sistemas Sockets : 33/70

Criao de um socket (2)


Nvel da Internet Cliente ou Servidor Aplicao API socket Socket Transporte Rede Ligao TCP ou UDP IP Gestor perifrico
Controlador perifrico Programao de Sistemas

Nvel do Linux Utilizador

Ncleo

Hardware
Sockets : 34/70

APUE 16.3.4

Associao dum socket a endereo/porto (1)


Um socket associado ao porto, por forma a ficar com com acesso exclusivo, atravs da funo
POSIX: #include <sys/socket.h> int bind(int, struct sockaddr*, socktlen_t);

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

Associao dum socket a endereo/porto (1)


No domnio da Internet, a constante INADDR_ANY determina que o socket fica automaticamente associado a todos os endereos Internet do n local. Nota: uma firewall possui duas placas de rede, uma ligada Internet e outra ligada rede local. A associao pode no ser necessria para alguns tipos de sockets
SOCK_DGRAM: se apenas forem enviados dados, porque o SO encontra um porto cada vez um pacote enviado. SOCK_STREAM: o destino determinado na altura do estabelecimento da ligao.
Programao de Sistemas Sockets : 36/70

Estruturas de dados panorama global


Curiosidade, para avaliao avanada apenas

A manipulao dos sockets envolve vrias estruturas de dados


Tabela de descritor de sockets 0: 1: 2: Estrutura socket proto family: PF_INET service: SOCK_STREAM Local address: Remote address: Estrutura endereo address family: AF_INET host IP: 193.136.143.1 port: 80

Programao de Sistemas

Sockets : 37/70

CcL:Comunicao com ligao


Servidor

Operaes tpicas do servidor e do cliente numa comunicao com ligao.


Cliente socket Abertura connect send Transferncia de dados recv close Fecho EOF Pedido ligao

socket bind Abertura

listen Aguarda pedido de ligao accept recv send recv close

Programao de Sistemas

Sockets : 38/70

CcL:Estabelecimento da ligao (1)


Para servios orientados ligao (sockets de tipo SOCK_STREAM ou SOCK_SEQPACKET) necessrio firmar a ligao antes dos dois ns trocarem dados. A. O cliente deve solicitar do servidor a ligao
POSIX: #include <sys/socket.h> int connect(int, struct sockaddr*, socktlen_t);

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

CcL:Estabelecimento da ligao (2)


O servidor pode encontrar-se indisponvel por razes diversas
Servidor desligado temporariamente Problemas na rede Sobrecarga de pedidos

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

CcL:Estabelecimento da ligao (3)


B. O servidor deve disponibilizar-se a acolher pedidos de ligaes:
POSIX: #include <sys/socket.h> int listen(int,int); O 1 parmetro identifica o descritor do socket do servidor. O 2 parmetro identifica o nmero mximo de pedidos que podem ficar pendentes numa fila (backlog). Nota1 : a funo listen no bloqueia. Nota2 : pedidos enviados depois da fila esgotada so rejeitados.

Programao de Sistemas

Sockets : 41/70

CcL:Estabelecimento da ligao (4)


Um pedido de ligao aceite pelo servidor atravs de
#include <sys/socket.h> int accept(int, struct sockaddr *, socklen_t *); O 1 parmetro identifica o descritor do socket do servidor. O 2 parmetro critrio de filtragem dos clientes. A funo retorna o descritor do socket que aceitou o estabelecimento da ligao. Nota1 : a funo accept bloqueia at chegada de um pedido de estabelecimento de ligao Nota2: se o servidor no se importar com o cliente, os 2 e 3 parmetros devem ser NULL.
Programao de Sistemas Sockets : 42/70

POSIX:

CcL:Leitura e escrita de dados


A comunicao com ligao feita de forma semelhante dos ficheiros e dos tubos
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.

O cliente recebe do terminal a mensagem a enviar para o servidor.


1. O servidor envia a mensagem recebida para o terminal, responde ao cliente e encerra. 2. O cliente fica espera da resposta, que afixada no terminal, e encerra.

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>

#define DIM 256 void error(char *msg) { perror(msg); exit(1); }

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

CsL:Comunicao sem ligao


Operaes tpicas do servidor e do cliente numa comunicao sem ligao.
Cliente socket Abertura bind sendto recvfrom recvfrom sendto Servidor socket Abertura bind

Programao de Sistemas

Sockets : 53/70

CsL:Leitura e escrita de dados (1)


Na comunicao sem ligao so necessrios parmetros extra
POSIX: #include <sys/types.h> #include <sys/socket.h> ssize_t sendto(int, char *, int, int, struct sockaddr *, socklen_t); Os 4 primeiros parmetros tm o mesmo significado de send.

O 5 parmetro identifica o endereo do destino.

Nota: o UDP s transfere mensagens at 8KB

Programao de Sistemas

Sockets : 54/70

CsL:Leitura e escrita de dados (2)


Na comunicao sem ligao a funo recv pode ser usada para leitura. Se o programador tiver necessidade de conhecer o n que enviou os dados, usar a funo
POSIX: #include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int, char *, int, int, struct sockaddr *, socklen_t); Os 4 primeiros parmetros tm o mesmo significado de recv.

O 5 parmetro identifica o endereo da fonte.

Programao de Sistemas

Sockets : 55/70

CcL e CsL: Fecho da ligao


O servidor e o cliente devem fechar o socket assim que terminarem a comunicao
POSIX: #include <sys/socket.h> int close(int);

O parmetro identifica o descritor do socket do servidor.

A funo
Fecha a ligao para SOCK_STREAM. Liberta o porto usado pelo socket.

Programao de Sistemas

Sockets : 56/70

Chamadas panorama global


Chamadas mais importantes da API de sockets

Programao de Sistemas

Sockets : 57/70

APUE 14.5.1

Tratamento de chamadas bloqueantes (1)


Curiosidade, para avaliao avanada apenas

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

Tratamento de chamadas bloqueantes (2)


Curiosidade, para avaliao avanada apenas

Para aplicaes complexas, o bloqueio prejudicial:


Ligaes mltiplas. Transmisses e recpes simultneas. Processamento simultneo no relacionado com a rede.

Vrias estratgias podem ser seguidas para tornear o problema do bloqueio:


Programao multiprocesso, ou multi-thread (desvantagens: programao mais complexa, problemas de sincronizao,...). Desligar o bloqueio, com a funo fcntl de controlo dos descritores de ficheiros (desvantagem: programao mais complexa de baixo nvel). Usar a chamada de sistema select (desvantagem: serializa tratamento, resposta prolongada-exemplo com acesso a disco-atrasa o tratamento das mensagens seguintes). Sockets : 59/70

Programao de Sistemas

Tratamento de chamadas bloqueantes (3)


Curiosidade, para avaliao avanada apenas POSIX: #include <sys/select.h> int select(int, fd_set *,fd_set *, fd_set *, struct timeval *);

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.

Nota: select pode ser usado para descritores de ficheiros.


Programao de Sistemas Sockets : 60/70

Tratamento de chamadas bloqueantes (4)


Curiosidade, para avaliao avanada apenas

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).

Nota: A configurao deve ser efectuada sempre antes da chamada ao select.


Programao de Sistemas Sockets : 61/70

Tratamento de chamadas bloqueantes (5)


Curiosidade, para avaliao avanada apenas

Exemplo Um servidor envia para o terminal dados vindos de


1. Teclado, ou 2. Rede, com transmisso de protocolo UDP e porto indicado na linha de comando.

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

Tratamento de chamadas bloqueantes (6)


Curiosidade, para avaliao avanada apenas

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>

#define WATCH 5 #define LEN 80 void error(char *msg) { perror(msg); exit(1); }

Programao de Sistemas

Sockets : 63/70

Tratamento de chamadas bloqueantes (7)


Curiosidade, para avaliao avanada apenas
int main(int argc, char **argv) { int sockfd; struct sockaddr_in serv_addr; struct sockaddr *cli_addr; socklen_t cli_len; fd_set rfds; struct timeval tv; int retval; char buf[LEN]; int size; /* open socket for Intenet communication */ if (argc < 2) { fprintf(stderr, "ERROR, no port provided!\n"); exit(1); } sockfd=socket(AF_INET, SOCK_DGRAM, 0); if (sockfd<0) error("ERROR opening socket");

Programao de Sistemas

Sockets : 64/70

Tratamento de chamadas bloqueantes (8)


Curiosidade, para avaliao avanada apenas
/* binds socket to port */ 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"); for(;;) { /* configure select parameters */ tv.tv_sec = WATCH; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(0, &rfds); /* stdin is fd[0] */ FD_SET(sockfd, &rfds);

Programao de Sistemas

Sockets : 65/70

Tratamento de chamadas bloqueantes (9)


Curiosidade, para avaliao avanada apenas
retval = select(sockfd+1, &rfds, NULL, NULL, &tv); if (retval == -1) error("ERROR on select"); else if (retval) { if (FD_ISSET(0, &rfds)) { size = read(0, &buf, LEN); buf[--size] = '\0'; /* replace \n by string delimiter */ printf(" *** Data from keyboard:%s ***\n",buf); } if (FD_ISSET(sockfd, &rfds)) { size = recvfrom(sockfd, &buf, LEN, 0, cli_addr, &cli_len); printf(" *** Data from abroad:%s ***\n",buf); } } else printf("No data within %d seconds.\n",WATCH); } exit(EXIT_SUCCESS); }

Programao de Sistemas

Sockets : 66/70

Tratamento de chamadas bloqueantes (10)


Curiosidade, para avaliao avanada apenas

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

Tratamento de chamadas bloqueantes (11)


Curiosidade, para avaliao avanada apenas
/* open socket for Intenet communication */ if (argc < 2) { fprintf(stderr, "ERROR, no port provided!\n"); exit(1); } sockfd=socket(AF_INET, SOCK_DGRAM, 0); if (sockfd<0) error("ERROR opening socket"); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("193.136.143.1");; serv_addr.sin_port = htons( atoi(argv[1]) ); for(;;) { printf("Message to be sent\n"); len=read(0, &buf, LEN); buf[len-1] = '\0'; nbytes = sendto( sockfd, buf, len, 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if(nbytes<0) error("ERROR on sendto"); } }

Programao de Sistemas

Sockets : 68/70

Tratamento de chamadas bloqueantes (12)


Curiosidade, para avaliao avanada apenas
[rgc@asterix Select]$ server 20000 Hello all! *** Data from keyboard:Hello all! *** No data within 5 seconds. *** Data from abroad:Hello from Canada! *** No data within 5 seconds. Bye! *** Data from keyboard:Bye! *** [rgc@asterix Select]$ [rgc@ottawa Select]$ client 20000 Message to be sent Hello from Canada! Message to be sent [rgc@ottawa Select]$

Programao de Sistemas

Sockets : 69/70

Erros na programao em sockets


Erros mais frequentes na programao em sockets:
Ordenao incorrecta de Bytes, por no insero de chamadas s funes hton() e ntoh(). Desacordo sobre dimenso dos registos de dados (fixos ou variveis). Problemas no select(). No observao do protocolo
Problema no abrangido nesta disciplina, A ter em ateno nas disciplinas Redes de Computadores Software de Telecomunicaes

Programao de Sistemas

Sockets : 70/70

S-ar putea să vă placă și