programação com sockets api sockets apareceu no bsd4.1 unix em 1981 são explicitamente criados,...

47
Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor dois tipos de serviço de transporte via API Sockets: datagrama não confiável fluxo de bytes, confiável Socket é uma interface (uma “porta”), local ao hospedeiro, criada por e pertencente à aplicação, e controlado pelo SO, através da qual um processo de aplicação pode tanto enviar como receber mensagens para/de outro processo de aplicação (remoto ou local) socket Meta: aprender a construir aplicações cliente/servidor que se comunicam usando sockets

Upload: internet

Post on 17-Apr-2015

142 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Programação com sockets

API Sockets apareceu no BSD4.1 UNIX

em 1981 são explicitamente

criados, usados e liberados por aplicações

paradigma cliente/servidor dois tipos de serviço de

transporte via API Sockets: datagrama não confiável fluxo de bytes, confiável

Socket é uma interface (uma “porta”), local ao

hospedeiro, criada por e pertencente à

aplicação, e controlado pelo SO, através da

qual um processo de aplicação pode tanto enviar como receber mensagens para/de outro processo de

aplicação (remoto ou local)

socket

Meta: aprender a construir aplicações cliente/servidor que se comunicam usando sockets

Page 2: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Serviços de Transporte

A camada de transporte dos protocolos TCP/IP fornece duas opções de tipos de serviço: Serviço orientado a conexão: utiliza o

protocolo TCP (Transmission Control Protocol) e garante entrega e ordenação.

Serviço datagrama: utiliza o protocolo UDP (User Datagram Protocol) e não faz nenhuma garantia.

Page 3: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Rotinas do S.O.

Sockets

Comandos no Hardware

Rotinas do Driver

API Sockets

Application Program Interface – Elemento de ligação entre uma aplicação e um sistema operacional de mais baixo nível.

Aplicação

Transporte

Rede

Enlace de Dados

Física

Sistema Operacional(Kernel)

Drivers e Hardware

Aplicação Final

Page 4: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Programação com sockets usando TCPSocket: Uma porta entre o processo de aplicação

e um protocolo de transporte fim-a-fim (UDP ou TCP)

Serviço TCP: Transferência confiável de bytes de um processo para outro

processo

TCP combuffers,

variáveis

socket

Controlado peloprogramador de

aplicação

Controladopelo sistemaoperacional

estação ouservidor

processo

TCP combuffers,

variáveis

socket

Controlado peloprogramador deaplicação

Controladopelo sistemaoperacional

estação ouservidor

internet

Page 5: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Cliente deve contactar servidor:

processo servidor deve antes estar em execução

servidor deve antes ter criado socket (porta) que aguarda contato do cliente

Cliente contacta servidor para:

criar socket TCP local ao cliente

especificar endereço IP, número de porta do processo servidor

Quando cliente cria socket: TCP cliente cria conexão com TCP do servidor

Quando contatado pelo cliente, o TCP do servidor cria socket novo para que o processo servidor possa se comunicar com o cliente permite que o servidor

converse com múltiplos clientes

Endereço IP e porta origem são usados para distinguir os clientes

TCP provê transferência confiável, ordenada de bytes

(“tubo”) entre cliente e servidor

ponto de vista da aplicação

Programação com sockets usando TCP

Page 6: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Comunicação entre sockets

Page 7: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

TCP: Gerenciamento de Conexões

Lembrete: Remetente, receptor TCP estabelecem “conexão” antes de trocar segmentos de dados

inicializam variáveis TCP: nos. de seq. buffers, info s/ controle

de fluxo (p.ex. RcvWindow)

cliente: iniciador de conexão servidor: contatado por

cliente

Inicialização em 3 tempos:

Passo 1: sistema cliente envia segmento de controle SYN do TCP ao servidor especifica no. inicial de seq não envia dados

Passo 2: sistema servidor recebe SYN, responde com segmento de controle SYNACK aloca buffers especifica no. inicial de seq.

servidor-> receptor

Passo 3: receptor recebe SYNACK, responde com segmento ACK que pode conter dados.

Page 8: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

TCP: Gerenciamento de Conexões (cont.)

Encerrando uma conexão:

cliente fecha soquete:

Passo 1: sistema cliente envia segmento de controle FIN ao servidor

Passo 2: servidor recebe FIN, responde com ACK. Encerra a conexão, enviando FIN.

cliente

FIN

servidor

ACK

ACK

FIN

fechar

fechar

fechada

esp

era

te

mpori

zada

Page 9: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

TCP: Gerenciamento de Conexões (cont.)

Passo 3: cliente recebe FIN, responde com ACK.

Entre em “espera temporizada” - responderá com ACK a FINs recebidos

Passo 4: servidor, recebe ACK. Conexão encerrada.

cliente

FIN

servidor

ACK

ACK

FIN

fechando

fechando

fechada

esp

era

tem

pori

zada

fechada

Page 10: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

TCP: Gerenciamento de Conexões (cont.)

Ciclo de vidade cliente TCP

Ciclo de vidade servidor TCP

Page 11: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Conceitos Importantes da Linguagem C e UNIX

Argumentos de Valor/Resultado Chamadas de Sistema de E/S Descritores de Arquivo Byte Ordering Portas e Endereços IP Associações & Conexões Serviços de Transporte

Page 12: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Argumentos de Valor/Resultado É possível (e comum) na linguagem C, utilizar o recurso

de passagem de argumentos por referência para passar valores para uma função ao mesmo tempo em que se espera um valor de retorno na mesma variável.

Exemplo: imagine uma função is_prime() que retorna 1 se um número apontado por um ponteiro n é primo e 0 (zero) se composto. Neste último caso, a função também retorna o número primo mais próximo do valor passado. Este segundo valor de retorno pode ser colocado no próprio endereço de memória referenciado por n.

int is_prime( int * n ){ /* verifica se (*n) é primo e em caso negativo coloca o primo mais próximo em (*n) */}

Page 13: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Chamadas de Sistema de E/S UNIX usa para toda E/S o paradigma open-

read-write-close. Por exemplo, open prepara um arquivo e retorna um

descritor, que será utilizado depois para operações read/write. O close fecha o arquivo.

#include <unistd.h>

int open( const char * filename, int oflag, ... );

int close( int fd );

size_t read( int fd, void * buffer, size_t n_bytes );size_t write( int fd, void * buffer, size_t n_bytes );

Page 14: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Descritores São números inteiros não negativos que

são ponteiros para estruturas de dados do sistema que representam os arquivos/dispositivos abertos por um processo.

7 26 15 50 39 21x

Descritoresde Arquivo y

z

Imagem do Processo Estruturas do S.O.

z

z

Page 15: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

A comunicação por sockets também usa descritores. Quando um socket é aberto, retorna um descritor, que pode ser utilizado por outras funções, como p-ex read e write.

Page 16: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

• Define como um valor é armazenado na memória.• Exemplo: 16909060 = 0x01020304

• Para evitar conflitos entre hosts de arquiteturas diferentes é convencionado que informações de controle na rede são armazenadas em Big-Endian.

Byte Ordering

Big-Endian Little-Endian

01

02

03

04

n

n+1

n+2

n+3

Endereço Memória

04

03

02

01

n

n+1

n+2

n+3

Endereço Memória

Page 17: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Endereços IP e Portas

Endereços IP identificam hosts na rede TCP/IP e são formados por 4 bytes, normalmente chamado octetos por razões históricas.

Portas são identificadores dos processos interessados em usar os recursos de rede em um host. Portas ocupam 2 bytes na memória.

146 164 10 2 39990

92 A4 0A 02 9C 36

Notação Padrão

Hexadecimal

Page 18: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Associações

Um processo precisa associar um socket a um endereço para “avisar” ao sistema operacional que deseja receber dados que chegam ao host com o endereço de destino especificado.

602789

1026

102

Processos20

23

146.164.41.10 : 80

25

41

146.164.41.10 : 21

146.164.41.10 : 20

EndereçoAssociadoS

ocke

ts

602789

1026

102

Processos20

23

146.164.41.10 : 80

25

41

146.164.41.10 : 21

146.164.41.10 : 20

146.164.41.10 : 56

EndereçoAssociadoS

ocke

ts

Page 19: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Conexões

Um socket pode ser conectado a um endereço diferente do seu próprio para que pacotes possam ser enviados por ele diretamente ao processo parceiro.

602Processo

20

EndereçoAssociadoS

ocke

t

200.128.40.12 : 10020

EndereçoConectado

146.164.41.10 : 13003

Page 20: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

accept( )

close( )

connect( )

socket( )

socket( )

bind( )

listen( )

close( )

Estabelecimentoda Conexão TCP

Cliente

Servidor

writen( )

readn( )

readn( )

writen( )

readn( )

Sockets em uma aplicação TCPFunções da API de sockets utilizadas para um cliente e um servidor se comunicarem usando TCP:

ter telefone

associar número ao telefone

ligar campainha

atender chamada

desligar

conversar

fazer chamada

desligar

conversar

Page 21: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets - Criação

Utiliza-se a chamada de sistema socket():

Parâmetros: domain – o tipo de rede do socket. Usamos AF_INET (Address

Family Internet). Outros tipos: AF_LOCAL, AF_INET6. type – o tipo de serviço de transporte. Para sockets TCP

usamos SOCK_STREAM, para UDP usamos SOCK_DGRAM. protocol – o protocolo utilizado. Passando 0 (zero) é utilizado

o padrão. A função retorna um descritor do socket criado ou –1 em

caso de erro.

#include <sys/types.h>#include <sys/socket.h>

int socket( int domain, int type, int protocol );

Page 22: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets - Endereços

Endereços IP e portas são armazenados em estruturas do tipo struct sockaddr_in.

sin_family é o tipo do endereço. AF_INET deve ser usado para endereçamento IPv4.

sin_port é a porta associada ao endereço.

sin_addr é uma estrutura que contém o endereço IP (os 4 octetos).

O endereço IP e a porta devem ser armazenados no byte order da rede (Big-Endian).

#include <netinet/in.h>

struct sockaddr_in { sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; /* ... outros campos */};

struct in_addr { in_addr_t s_addr;};

uint16 htons( uint16 data_in_host_order );uint16 ntohs( uint16 data_in_net_order );

uint32 htonl( uint32 data_in_host_order );uint32 ntohl( uint32 data_in_net_order );

Page 23: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets - Associação

Utiliza-se a chamada de sistema bind():

Parâmetros: sockfd – o descritor do socket. my_addr – a estrutura com o endereço para ser associado. addrlen – o tamanho da estrutura do endereço.

A função retorna 0 (zero) em caso de sucesso ou –1 no caso de um erro.

Erro comum: EADDRINUSE (“Address already in use”)

#include <sys/types.h>#include <sys/socket.h>

int bind( int sockfd, struct sockaddr *my_addr, socklen_t addrlen );

Page 24: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets – Traduzindo Endereços IP

Para converter um endereço IP entre as formas de string e binária:

A função inet_aton() converte um endereço na notação do ponto (1.2.3.4) para o formato binário em byte order de rede (como a struct sockaddr_in espera) e retorna 0 (zero) em caso de sucesso.

A função inet_ntoa() faz a conversão oposta.

#include <arpa/inet.h>

int inet_aton(const char * str, struct in_addr * addrptr);char * inet_ntoa(struct in_addr addr);

Page 25: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets – Resolvendo Nomes com DNS

Para resolver nomes de hosts (www.land.ufrj.br) para endereços IP (146.164.47.193) usamos as rotinas de acesso ao serviço DNS:

#include <netdb.h>

struct hostent * gethostbyname(const char * str);

struct hostent { int h_length; /* tamanho do endereço */ char **h_addr_list; /* lista de endereços */ char *h_addr; /* primeiro endereço */ /* ... outros campos */}

Page 26: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets TCP

Sockets orientados a conexão com garantias de entrega e ordenação.

É preciso estabelecer a conexão antes da troca de dados.

O servidor cria um socket especial para “escutar” pedidos de conexão do cliente.

Cada vez que o servidor aceita um pedido de conexão recebido no socket de escuta, um novo socket é criado para realizar a comunicação. Assim é possível para o servidor voltar a aceitar novos pedidos de conexão mais tarde (usando o socket de escuta).

Page 27: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets TCP – listen()

Para por um socket em modo de escuta usamos a chamada de sistema listen():

Parâmetros: sockfd – o descritor do socket. backlog – a soma das filas de conexões completas e

incompletas. Este parâmetro é extremamente dependente da implementação do Sistema Operacional.

O valor de retorno da função é 0 (zero) em caso de sucesso ou –1 caso contrário.

#include <sys/socket.h>

int listen( int sockfd, int backlog );

Page 28: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets TCP – accept()

Esta função aceita pedidos de conexão pendentes ou fica bloqueada até a chegada de um.

Parâmetros: sockfd – o descritor do socket. cliaddr – a estrutura onde será guardado o endereço do

cliente. addrlen – argumento valor/resultado com o tamanho da

estrutura do endereço. O valor de retorno da função é um novo descritor (não

negativo) em caso de sucesso ou –1 caso contrário. Cada novo descritor retornado por accept() está associado

à mesma porta do socket de escuta.

#include <sys/socket.h>

int accept( int sockfd, struct sockaddr * cliaddr, socklen_t * addrlen );

Page 29: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets TCP – send()

Usada para enviar dados por um socket conectado.

Parâmetros: sockfd – o descritor do socket. buffer – um ponteiro para os dados a serem enviados. n_bytes – quantidade de bytes a serem enviados a partir

do ponteiro buffer. flags – opções para essa operação.

O valor de retorno da função é a quantidade de bytes enviados em caso de sucesso ou –1 caso contrário.

#include <sys/socket.h>

int send( int sockfd, void * buffer, size_t n_bytes, int flags );

Page 30: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets TCP – recv()

Recebe dados por um descritor conectado, ou bloqueia a execução até que algum dado chegue ao socket:

Parâmetros: sockfd – o descritor do socket. buffer – um ponteiro para a área de memória onde devem

ser armazenados os dados recebidos. n_bytes – quantidade máxima de bytes a serem

recebidos. flags – opções para essa operação.

O valor de retorno da função é a quantidade de bytes recebidos em caso de sucesso ou –1 caso contrário.

#include <sys/socket.h>

int recv( int sockfd, void * buffer, size_t n_bytes, int flags );

Page 31: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>

int main( int argc, char ** argv ){ int sockfd; char recvline[30]; struct sockaddr_in servaddr;

if( argc != 2 ) return –1;

sockfd = socket( AF_INET, SOCK_STREAM, 0 );

memset( &servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(12345); inet_aton( argv[1], &servaddr.sin_addr );

connect( sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr) );

readn( sockfd, recvline, 30 ); fputs( recvline, stdout ); close( sockfd );

return 0;}

Exemplo – Um Cliente TCP

Inicializar a estrutura servaddr com zeros.

Preencher os campos da estrutura servaddr:

sin_family com o tipo de endereço (AF_INET)

sin_port com a porta (12345) no byte order da rede.

sin_addr com o endereço passado como argumento para o programa.

Conecta o socket com o endereço do servidor (servaddr). Isto irá estabelecer a conexão TCP entre o cliente e o servidor.

Lê 30 bytes do socket. Esta função pode ler menos bytes se o outro lado (o servidor) fechar a conexão.

Imprime os dados recebidos na saída padrão.

Fecha o socket.

Criar um socket para rede TCP/IP (AF_INET), orientado a conexão (SOCK_STREAM), usando TCP (o protocolo padrão dado por 0).

Page 32: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <netinet/in.h>

int main( int argc, char ** argv ){ int listenfd, connfd, size; struct sockaddr_in myaddr, cliaddr;

listenfd = socket( AF_INET, SOCK_STREAM, 0 );

memset( &myaddr, 0, sizeof(myaddr) ); myaddr.sin_family = AF_INET; myaddr.sin_port = htons(12345); myaddr.sin_addr.s_addr = INADDR_ANY;

bind( listenfd, (struct sockaddr *)&myaddr, sizeof(myaddr) );

listen( listenfd, 5 );

for( ; ; ) { memset( &cliaddr, 0, sizeof(cliaddr) ); size = sizeof( cliaddr ); connfd = accept( listenfd, (struct sockaddr *)&cliaddr, &size ); writen( connfd, “Alo Mundo”, 10 ); close( connfd ); }

return 0;}

Preencher a estrutura do endereço local (myaddr) para associação com o socket:

sin_addr contém o endereço IP pelo qual o processo deseja receber pacotes. Como uma máquina pode ter vários IPs, é mais prático especificar que se deseja receber pacotes para qualquer um deles. Para isso usamos a constante INADDR_ANY.

Exemplo – Um Servidor TCP

Associar o endereço preenchido com o socket, para informar o S.O. de que o processo deseja receber pacotes para este endereço.

Aguarda um pedido de conexão.

Envia uma mensagem de 10 bytes pelo socket.

Fecha o socket da conexão.

Volta a aceitar novos pedidos.

Colocar o socket em modo de escuta. Isto cria uma fila de pedidos de conexão para o socket.

Page 33: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Servidores Concorrentes

Muitas vezes é necessário para um servidor lidar com vários clientes de uma única vez. Para conseguir isto é preciso, de alguma maneira, voltar a aceitar conexões, sem esperar que um cliente seja completamente servido.

Isto normalmente é feito através da criação de novas threads ou novos processos.

Um servidor, após o retorno da função accept(), se divide em dois, e enquanto uma linha de execução se dedica a atender o cliente, outra volta a esperar por novos pedidos de conexão.

Page 34: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Servidores concorrentesEsquema de um Servidor Típico

pid_t pid;int listenfd, confd;

listenfd = socket(...);bind(listenfd, ...);listen(listenfd, LISTENQ);

for( ; ; ) {

connfd = accept(listenfd, ...);

if ( ( pid = fork() ) == 0 ){

close(listenfd);

doit(connfd);

close(connfd);exit(0)

}

close (connfd);}

Page 35: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Conclusões sobre sockets TCP Um par de aplicações que se comunicam por TCP em

geral tem a seguinte forma:

accept( )

close( )

connect( )

socket( )

socket( )

bind( )

listen( )

close( )

Troca de Dados

Estabelecimentoda Conexão TCP

Cliente

Servidor

ServidoresConcorrentes

Page 36: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Programação com sockets usando UDPUDP: não tem “conexão”

entre cliente e servidor não tem “handshaking” remetente coloca

explicitamente endereço IP e porta do destino

servidor deve extrair endereço IP, porta do remetente do datagrama recebido

UDP: dados transmitidos podem ser recebidos fora de ordem, ou perdidos

UDP provê transferência não confiável de grupos de bytes (“datagramas”) entre cliente e servidor

ponto de vista da aplicação

Page 37: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets UDP

Sockets sem conexão e sem garantias de entrega ou ordenação.

Só é preciso saber o endereço de destino antes de enviar dados. É possível receber dados a qualquer momento e de qualquer um. Usamos as funções sendto() e recvfrom().

Pode-se ainda usar a função connect() com sockets UDP, mas o seu significado aqui é diferente, uma vez que NÃO faz sentido falar em uma conexão UDP. Para sockets UDP, a função connect() apenas “fixa” o endereço conectado. Assim é possível usar as funções send() e recv() como para sockets TCP.

Page 38: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets UDP – sendto()

Envia dados por um socket NÃO conectado.

Parâmetros: sockfd – o descritor do socket. buffer – um ponteiro para os dados a serem enviados. n_bytes – quantidade de bytes a serem enviados. flags – opções para essa operação. to – endereço de destino dos dados. addrlen – tamanho em bytes do endereço de destino.

O valor de retorno da função é a quantidade de bytes enviados em caso de sucesso ou –1 caso contrário.

#include <sys/socket.h>

int sendto( int sockfd, void * buffer, size_t n_bytes, int flags, const struct sockaddr * to, socklen_t addrlen );

Page 39: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Sockets UDP – recvfrom()

Recebe dados por um descritor NÃO conectado, ou bloqueia a execução até que algum dado chegue:

Parâmetros: sockfd – o descritor do socket. buffer – um ponteiro para a área de memória onde devem ser

armazenados os dados recebidos. n_bytes – quantidade máxima de bytes a serem recebidos. flags – opções para essa operação. from – ponteiro para a estrutura onde será escrito o endereço de origem. addrlen – argumento valor/resultado com o tamanho do endereço de

origem. O valor de retorno da função é a quantidade de bytes recebidos em

caso de sucesso ou –1 caso contrário.

#include <sys/socket.h>

int recvfrom( int sockfd, void * buffer, size_t n_bytes, int flags, struct sockaddr * from, socklen_t * addrlen );

Page 40: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>

int main( int argc, char ** argv ){ int sockfd; struct sockaddr_in servaddr;

if( argc != 2 ) return –1;

sockfd = socket( AF_INET, SOCK_DGRAM, 0 );

memset( &servaddr, 0, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(12345); inet_aton( argv[1], &servaddr.sin_addr );

sendto( sockfd, “Alo Servidor”, 13, MSG_WAITALL,

(struct sockaddr *)&servaddr, sizeof(servaddr) );

close( sockfd );

return 0;}

Exemplo – Um Cliente UDP

Inicializar a estrutura servaddr com zeros.

Preencher os campos da estrutura servaddr:

sin_family com o tipo de endereço (AF_INET)

sin_port com a porta (12345) no byte order da rede.

sin_addr com o endereço passado como argumento para o programa.

Envia 13 bytes de dados para o servidor.

Criar um socket para rede TCP/IP (AF_INET), orientado a datagramas (SOCK_DGRAM), usando UDP (o protocolo padrão dado por 0).

Page 41: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <netinet/in.h>

int main( int argc, char ** argv ){ int sockfd, size, n; struct sockaddr_in myaddr;

sockfd = socket( AF_INET, SOCK_DGRAM, 0 );

memset( &myaddr, 0, sizeof(myaddr) ); myaddr.sin_family = AF_INET; myaddr.sin_port = htons(12345); myaddr.sin_addr.s_addr = INADDR_ANY;

bind( sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr) );

for( ; ; ) { recvfrom( sockfd, recvline, 30,

MSG_WAITALL, NULL, NULL ); fputs( recvline, stdout ); }

return 0;}

Exemplo – Um Servidor UDP

Associar o endereço preenchido com o socket, para informar o S.O. de que o processo deseja receber pacotes para este endereço.

Aguarda até 30 bytes. É possível para esta função retornar antes se o outro lado enviar um datagrama menor.

Imprime os dados recebidos na saída padrão.

Page 42: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Conclusões sobre sockets UDP

Um par de aplicações que se comunicam por UDP em geral tem a seguinte forma:

close( )

socket( ) socket( )

bind( )

close( )

Troca de Dados

Cliente Servidor

bind( )

Page 43: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Esta é a forma mais simples de depurar aplicações que envolvem sockets, threads e mais de um processo.

Atenção! Deve-se gerar as mensagens de aviso em ‘stderr’ (que não possui buffer) e não ‘stdout’!

Inconveniente desta técnica de depuração: pode afetar o funcionamento do programa.

Depurando: Passo 0,Exibindo mensagens de aviso

Page 44: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

Depurando: Passo 1,A Máquina de Estados

Comando chave: netstat -a

Page 45: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

[sadoc@copa src]$ netstat -a | grep 32568Proto Local Address Foreign Address State tcp *:32568 *:* LISTEN tcp localhost:47415 localhost:32568 ESTABLISHED tcp localhost:32568 localhost:47415 ESTABLISHED

[sadoc@copa src]$ netstat -a | grep 32568tcp localhost:47415 localhost:32568 CLOSE_WAIT tcp localhost:32568 localhost:47415 FIN_WAIT2

Depurando: Passo 1, A Máquina de Estados do TCP

Comando chave: netstat -a

wildcard

Page 46: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

tcpdump -x src host_name > log_file

Programa equivalente, com interface gráfica: ethereal

Depurando: Passo 2,O comando tcpdump

Imprime o conteúdo de cada pacote,em hexadecimal

Fonte dos pacotes

Page 47: Programação com sockets API Sockets apareceu no BSD4.1 UNIX em 1981 são explicitamente criados, usados e liberados por aplicações paradigma cliente/servidor

2b: Camada de Aplicação

Bibliografia Recomendada

Stevens, W. R. – UNIX Network Programming:

Volume I – Networking APIs: Sockets and XTI

Comer, D.E.; Stevens, D.L. – TCP/IP Client-Server

Programming and Aplications, vol.3, Linux POSIX

Socket Version

Frost J. – BSD Sockets: A quick and dirty primer.

http://www.frostbytes.com/~jimf/papers/sockets/sock

ets.html).