Sumário ● Introdução ao TCP/IP e à Internet ● API Sockets para comunicação via redes ● Exemplos A Internet: Endereços ● ● Cada computador ligado à Internet tem um endereço único que o distingue dos restantes (endereço IP) O endereço é composto por 4 números de 0­255 Ex: www.slashdot.org é 66.35.250.151 A Internet: Protocolo UDP ● ● A informação é introduzida na rede em pacotes. Cada pacote segue o seu caminho para o destinatário de forma independente. ● Pacotes podem chegar ao destino fora de ordem! ● Pacotes podem ser perdidos e nem chegar ao destino! A Internet: Protocolo TCP ● ● ● É primeiro estabelecido um canal lógico entre dois extremos. A informação é enviada através do canal para o destinatário como uma sequência contínua de bytes. Os bytes chegam ao destino pela mesma ordem pela qual são enviados, e não se perdem. A Internet: Portos Problema: ● ● Um computador pode ter vários programas (processos) a executar em simultâneo (IRC, teleconferência, web browser, etc...) Como se sabe a que programa se destina cada pacote que chega ao computador? Solução: ● ● ● Conceito de porto: um computador, vários portos (0­65535) Cada pacote, para além do endereço IP do destinatário, contem ainda o número do porto do destino. Cada programa recebe os pacotes recebidos num porto A Internet: Portos ● Tanto o emissor como o receptor recorrem a um porto para enviar/receber informação. Modelo Cliente/Servidor ● ● Cliente envia pedido (ex. Browser pede a página index.html) Servidor responde (ex. Envia o conteúdo do ficheiro com nome index.html) Sumário ● Introdução ao TCP/IP e à Internet ● API Sockets para comunicação via redes ● Exemplos Conceito de Socket Computador Computador Aplicação Aplicação socket associação entre socket e porto portos Carta Rede (endereço IP) Conexão TCP Carta Rede (endereço IP) Criação e Destruição de um Socket ● ● int socket(int domain, int type, int protocol) – Cria um socket – Domain ­> PF_INET (família de protocolos internet) – Type – Protocol ­> 0 ­> SOCK_STREAM (para conexão TCP) SOCK_DGRAM (para envio de pacotes UDP) int close(int sockfd) – Destroi um socket – sockfd deverá ser o inteiro retornado pela função socket() Associação de um Socket a um Porto ● int bind( int sockfd, struct sockaddr *address, int sockaddr_len) – Associa um socket a um porto local – sockfd é o socket a ser associado. – *address é um apontador para uma estrutura que contem o porto e endereço IP ao qual o socket deverá ser associado – sockaddr_len é o comprimento em bytes da estrutura atrás ex: sizeof(address) Estabelecimento de uma Conexão ● int connect(int sockfd, const struct sockaddr *address, int sockaddr_len) – Conecta um socket a um porto remoto – sockfd é o socket a ser conectado. – *address é um apontador para uma estrutura que contem o porto e endereço IP ao qual o socket deverá ser conectado – sockaddr_len é o comprimento em bytes da estrutura atrás ex: sizeof(address) Envio e Recepção de Dados Através de Sockets ● ● int write(int sockfd, char *buffer, int len) – Envia len bytes de dados do buffer pelo socket sockfd – buffer ­> apontador para local onde estão armazenados os dados a ser enviados – len ­> número de bytes a serem enviados – retorna ­> número de bytes efectivamente enviados int read(int sockfd, char *buffer, int len) – Copia os bytes recebidos pelo socket para o buffer. – len ­> número de máximo de bytes a serem copiados – retorna ­> número de bytes efectivamente copiados Sequência de Chamadas Para Troca de Dados por Sockets UDP s1 = socket(PF_INET, SOCK_DGRAM, 0) pacotes na rede s2 = socket(PF_INET, SOCK_DGRAM, 0) bind(s1, &addr1, sizeof(addr1)) bind(s2, &addr2, sizeof(addr2)) connect(s1, &addr2, sizeof(addr2)) message2 = malloc(100) write(s1, “Hello there...”, 15) message1 = malloc(100) read(s1, &message, 100) read(s2, &message, 100) connect(s2, &addr1, sizeof(addr1)) write(s2, “Hi partner...”, 14) Nota: Existem outras sequências válidas para sockets UDP recorrendo às funções sendto(...), recvfrom(...), etc... Sequência de Chamadas Para Troca de Dados por Sockets TCP s1 = socket(PF_INET, SOCK_DGRAM, 0) pacotes na rede s2 = socket(PF_INET, SOCK_STREAM, 0) bind(s2, &addr2, sizeof(addr2)) connect(s1, &addr2, sizeof(addr2)) listen(s2, 1) s3 = accept(s2, NULL, NULL) message2 = malloc(100) write(s1, “Hello there...”, 15) read(s3, &message, 100) message1 = malloc(100) read(s1, &message, 100) write(s3, “Hi partner...”, 14) Nota: Existem outros pacotes do protocolo TCP que são trocados de forma automática e que não se encontram representados. Pedido de Conexão Computador Computador Cliente s1 Servidor (3) s2 socket associação entre socket e porto s3 (2) (4) portos Carta Rede (endereço IP) (1) (5) Conexão TCP Estabelecimento de uma Conexão (Lado do Servidor) ● ● int listen(int sockfd, int backlog) – Coloca o socket sockfd no modo de aceitação de pedidos de estabelecimentos de conexões – backlog ­> número máximo de pedidos de conexão pendentes int accept(int sockfd, struct sockaddr *address, int *sockaddr_len) – Aceita pedidos de conexão – Retorna um terceiro socket conectado ao socket remoto de onde originou o pedido de conexão. – *address é um apontador para uma estrutura que será preenchida com o porto e endereço IP do socket remoto A Estrutura dos Endereços #include <netinet/in.h> struct sockaddr_in address; address.sin_family = AF_INET; address.sin_port = htons(8080); address.sin_addr.s_addr = inet_addr (“1.2.3.4”); – sin_family ­> familia de endereço AF_INET (Address Family Internet) – sin_port ­> porto (em Network Byte Order = MSB first) – sin_addr.s_addr ­> endereço IP (em Network Byte Order)