comunicação entre processos usando sockets disciplina: linguagem de programação iv

62
Comunicação entre Comunicação entre processos usando Sockets processos usando Sockets Disciplina: Linguagem de Programação IV Disciplina: Linguagem de Programação IV

Upload: duff

Post on 21-Jan-2016

36 views

Category:

Documents


0 download

DESCRIPTION

Comunicação entre processos usando Sockets Disciplina: Linguagem de Programação IV. Revisão da aula anterior. Revisão do programa fork. Quais são os problemas em relação aos processos pesados ?. Comunicação entre processos. send / receive (troca de mensagens) RPC ( Remote Procedure Call ) - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Comunicação entre processos Comunicação entre processos usando Sockets usando Sockets

Disciplina: Linguagem de Programação IVDisciplina: Linguagem de Programação IV

Page 2: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Revisão da aula anteriorRevisão da aula anterior

Revisão do programa fork.Revisão do programa fork.

Quais são os problemas em relação aos processos pesados ?Quais são os problemas em relação aos processos pesados ?

Page 3: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Comunicação entre processosComunicação entre processos

send / receive (troca de mensagens)send / receive (troca de mensagens)

RPC (RPC (Remote Procedure CallRemote Procedure Call)) C. 1984, ex.: C. 1984, ex.: rpcinfo/portmapper.rpcinfo/portmapper. Objetos distribuídos. Maior nível de abstração.Objetos distribuídos. Maior nível de abstração.

Page 4: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

API: Application Programming interfaceAPI: Application Programming interface

API: Modelo de ProgramaçãoAPI: Modelo de Programação

disponível em muitos sistemas operacionais disponível em muitos sistemas operacionais ex: Windows NT, Unix, etc.ex: Windows NT, Unix, etc.

Facilita a ProgramaçãoFacilita a Programação

Torna as aplicações mais flexíveis Torna as aplicações mais flexíveis

Page 5: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Revisão SocketsRevisão Sockets

O que é um Socket?O que é um Socket?

Socket é uma ponta de uma comunicação ponto-a-ponto entre dois Socket é uma ponta de uma comunicação ponto-a-ponto entre dois programas rodando em uma rede.programas rodando em uma rede.

Page 6: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

A API SOCKET A API SOCKET Introduzido em 1981 no UNIX BSD(Berkeley Introduzido em 1981 no UNIX BSD(Berkeley

Software Distribution) 4.1Software Distribution) 4.1

Page 7: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

A API SOCKET A API SOCKET

Page 8: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

A API SOCKETA API SOCKET - cont. - cont.

Cada aplicação conhece apenas o seu próprio Socket;Cada aplicação conhece apenas o seu próprio Socket;

Os sockets são explicitamente criados, usados e Os sockets são explicitamente criados, usados e liberados pela própria aplicação;liberados pela própria aplicação;

Baseado no paradigma cliente/servidor;Baseado no paradigma cliente/servidor;

dois tipos de serviço de transporte via API socket:dois tipos de serviço de transporte via API socket: datagramas não confiáveis datagramas não confiáveis confiáveis, orientado a conexãoconfiáveis, orientado a conexão

Page 9: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Sockets: visão conceitualSockets: visão conceitual

cada socket possui o seu próprio buffer para envio cada socket possui o seu próprio buffer para envio e recepção de dado, número de porta, parâmetro;e recepção de dado, número de porta, parâmetro;

As operações com o socket são construídas como As operações com o socket são construídas como chamada a funções do sistema operacional.chamada a funções do sistema operacional.

Page 10: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Endereçamento na InternetEndereçamento na Internet

Cada máquina na Internet possui um ou mais Cada máquina na Internet possui um ou mais endereços IP 32-bit únicos e globais;endereços IP 32-bit únicos e globais;

A máquina pode ter 1 ou mais endereçosA máquina pode ter 1 ou mais endereços cada endereço está associado a cada placa de redecada endereço está associado a cada placa de rede

Notação de ponto decimal:Notação de ponto decimal: 4 inteiros decimais , cada grupo representando um byte de 4 inteiros decimais , cada grupo representando um byte de

endereço IP.endereço IP.

Page 11: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Endereçamento na InternetEndereçamento na Internet

A função A função inet_addr() converte da notação ponto converte da notação ponto decimal para o endereço de 32-bit;decimal para o endereço de 32-bit;

A função A função gethostbyname() converte o nome converte o nome textual para o ponto decimal. textual para o ponto decimal.

Page 12: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

DNS: Sistema de nomes de Domínio na DNS: Sistema de nomes de Domínio na InternetInternet

uma base de dados distribuída usada por uma base de dados distribuída usada por aplicações TCP/IP para mapear de/para nomes aplicações TCP/IP para mapear de/para nomes de máquina para/de endereços IP.de máquina para/de endereços IP.

servidor de nomes:servidor de nomes: as funções de usuário gethostbyname() e as funções de usuário gethostbyname() e

gethostbyaddress() contactam o servidor de nome gethostbyaddress() contactam o servidor de nome local através da porta 53local através da porta 53

o servidor de nomes retorna um endereço IP do nome o servidor de nomes retorna um endereço IP do nome da máquina solicitadada máquina solicitada

Page 13: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Criando um socket Criando um socket Mesmo ponto comum (socket) usado para enviar/receber Mesmo ponto comum (socket) usado para enviar/receber

dados dados

não existe, a priori, associação do socket com a redenão existe, a priori, associação do socket com a rede

deve especificar a família de protocolo, bem como o nível deve especificar a família de protocolo, bem como o nível do serviço a ser usado com o socket: do serviço a ser usado com o socket:

Tipo de serviço:Datagrama (SOCK_DGRAM) = UDPConfiável (SOCK_STREAM) = TCP

Page 14: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Criando um socketCriando um socket - cont. - cont.

int socket (int socket (int family, int service, int int family, int service, int protocolprotocol) )

familyfamily ₫₫ um nome simbólico para a família de protocolos um nome simbólico para a família de protocolos serviceservice ₫₫ um nome simbólico para o tipo de serviço um nome simbólico para o tipo de serviço ProtocolProtocol ₫₫ para uso futuro. Esse valor será 0. para uso futuro. Esse valor será 0. Obs.: O código de retorno da função socket() é um descritor, usado em todas as Obs.: O código de retorno da função socket() é um descritor, usado em todas as

chamadas ao socket criado.chamadas ao socket criado.

Exemplo: Exemplo:

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

int sockfd; int sockfd; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)0) { /* handle error */ } { /* handle error */ }

Page 15: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Atribuindo um endereço de rede ao socket: Atribuindo um endereço de rede ao socket: bind()bind()

Cada socket deve ser associado a uma porta local Cada socket deve ser associado a uma porta local que deve ser única.que deve ser única. A porta é uma abstração do protocolo TCP/IP para A porta é uma abstração do protocolo TCP/IP para

distinguir entre múltiplos destinos dentro de uma distinguir entre múltiplos destinos dentro de uma determinada máquinadeterminada máquina

Precisa especificar o endereço de redePrecisa especificar o endereço de rede O S.O. sabe que as messagens recebidas naquele O S.O. sabe que as messagens recebidas naquele

endereço e porta devem ser entregues para o socket.endereço e porta devem ser entregues para o socket.

Endereço de portas. Ver arquivos /etc/services.Endereço de portas. Ver arquivos /etc/services.

Page 16: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Endereçamento de Socket: estruturas de Endereçamento de Socket: estruturas de endereço pré-definidasendereço pré-definidas

Especificando endereços de socket: algumas estruturas de Especificando endereços de socket: algumas estruturas de dados usadas na implementação:dados usadas na implementação:

struct sockaddr_in { struct sockaddr_in { short sin_family; /* default short sin_family; /* default AF_INET */ AF_INET */ u_short sin_port; /* número de 16 bit */u_short sin_port; /* número de 16 bit */ struct in_addr sin_addr; /* endereçstruct in_addr sin_addr; /* endereço de 32 bit o de 32 bit da máquina */ da máquina */ char sin_zero[8]; /* nchar sin_zero[8]; /* nãão usado */o usado */

};};

struct in_addr { struct in_addr { u_long s_addr; /* end. 32 bit da máquina */u_long s_addr; /* end. 32 bit da máquina */}; };

Page 17: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

A chamada ao bind()A chamada ao bind()

int bind (int bind ( int sockfd, struct sockaddr *myaddr, int addresslen int sockfd, struct sockaddr *myaddr, int addresslen))

sockfd: ésockfd: é o número do socket obtido anteriormente. o número do socket obtido anteriormente. *myaddr:*myaddr: especifica o end. local associado ao especifica o end. local associado ao

socket(inclusive a porta). socket(inclusive a porta). addresslen: éaddresslen: é o tamanho da estrutura de endere o tamanho da estrutura de endere₤₤oo

Obs.: se a função retornar um erro então o número da porta já Obs.: se a função retornar um erro então o número da porta já está em uso ou fora do limite.está em uso ou fora do limite.

Page 18: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

A chamada ao bind()A chamada ao bind() - cont. - cont.

#include <sys/types.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/socket.h>#include <#include <inet.h>inet.h>int sockfd;int sockfd;struct sockaddr_in myaddr;struct sockaddr_in myaddr; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)0)

{ /* Manipulador de erro */ }{ /* Manipulador de erro */ } myaddr.sin_family = AF_INET;myaddr.sin_family = AF_INET; myaddr.sin_port = htons(5100); myaddr.sin_port = htons(5100); myaddr.sin_addr.s_addr = htonl(INADDR_ANY); myaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* INADDR_ANY = SO determina o hostid *//* INADDR_ANY = SO determina o hostid */ if ( bind(sockfd, (struct sockaddr *) &myaddr, if ( bind(sockfd, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {sizeof(myaddr)) < 0) { /* Manipulador de erro*/ /* Manipulador de erro*/

}}

Page 19: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Serviço Orientado a ConexãoServiço Orientado a Conexão

Page 20: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

SERVIDOR

Atribui um endereAtribui um endere₤₤ooao descritorao descritor:bind()bind()

CLIENTEcria o descritor:cria o descritor:socket()socket()

Atribui ao descritorAtribui ao descritorum endereum endere₤₤oo(opcional) :(opcional) :bind()bind()

Avisa que está aceitandoAvisa que está aceitandoconexões: conexões: listen()listen()

bloquea/esperabloquea/esperanovas conexões.:novas conexões.:accept()accept()(novos (novos sockets criados na volta)sockets criados na volta)

espera pelo pkt:espera pelo pkt:recv()recv()

envia resposta:envia resposta:send()send()

Conectar o servidor Conectar o servidor via socket: via socket: connect()connect()

Libera o descritor:Libera o descritor:close()close()

envia msg:envia msg: send() send()

espera a resp:espera a resp:recv()recv()

Cria o descritor:Cria o descritor:socket() socket() para receber pedidospara receber pedidos

Libera o descritor:Libera o descritor:close()close()

Determina o end. servidorDetermina o end. servidor

Troca de msg

Requisita

resposta

Page 21: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Serviço Orientado a ConexãoServiço Orientado a Conexão

aperto de mão cliente/servidor:aperto de mão cliente/servidor: cliente deve se conectar ao servidor antes de enviar ou cliente deve se conectar ao servidor antes de enviar ou

receber dadosreceber dados cliente não passará do connect() até o servidor aceitá-locliente não passará do connect() até o servidor aceitá-lo servidor deve aceitar o cliente antes de enviar ou receber servidor deve aceitar o cliente antes de enviar ou receber

dadosdados servidor não passará do accept() até o cliente usar servidor não passará do accept() até o cliente usar

connect()connect()

serviço orientado a conexão: serviço confiável serviço orientado a conexão: serviço confiável oferecido pela camada de transporteoferecido pela camada de transporte..

Page 22: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

conexão cliente-para-servidor : conexão cliente-para-servidor : connect() connect()

cliente usa cliente usa connect() connect() para requisitar conexão junto ao para requisitar conexão junto ao servidorservidor

protocolo da camada de transporte (ex: TCP) inicia protocolo da camada de transporte (ex: TCP) inicia procedimento para conexão através do aperto de mão procedimento para conexão através do aperto de mão cliente/servidorcliente/servidor

connect()connect() retorna quando o servidor aceita a conexão ou retorna quando o servidor aceita a conexão ou time-out (não há resposta)time-out (não há resposta)

usado com protocolos confiáveis, mas também com usado com protocolos confiáveis, mas também com datagramasdatagramas

Page 23: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Conexão cliente-para-servidor : Conexão cliente-para-servidor : connect()connect() - cont. - cont.

int connect (int connect ( int sockfd, struct sockaddr *toaddrptr, int int sockfd, struct sockaddr *toaddrptr, int addresslenaddresslen))

sockfdsockfd:: número do socket atribuído anteriormente. Os número do socket atribuído anteriormente. Os processos o usam para enviar conexões aceitas.processos o usam para enviar conexões aceitas.

*toaddrptr:*toaddrptr: especifica o end. Remoto (inclusive a porta).especifica o end. Remoto (inclusive a porta).

AddresslenAddresslen : : é o tamanho da estrutura de endereço.é o tamanho da estrutura de endereço.

Page 24: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

A chamada listen() A chamada listen()

Usado por servidores orientados a conexão.Usado por servidores orientados a conexão. avisa a rede/S.O. que o servidor aceitará requisições para avisa a rede/S.O. que o servidor aceitará requisições para

conexão.conexão. NãoNão bloqueia e não espera por requisições!bloqueia e não espera por requisições!

int listen ( int sockfd, int maxwaiting)int listen ( int sockfd, int maxwaiting) sockfd:sockfd: número do socket atribuído anteriormente. número do socket atribuído anteriormente. maxwaiting:maxwaiting: número máximo de conexões que podem ser número máximo de conexões que podem ser

enfileiradas, enquanto aguardam o servidor executar um enfileiradas, enquanto aguardam o servidor executar um accept()accept().. O valor típico é 5. O valor típico é 5.

Page 25: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Conexão servidor-para-cliente : accept() Conexão servidor-para-cliente : accept() Executado pelo servidor após Executado pelo servidor após listen().listen().

servidor irá aceitar as novas conexões via socket servidor irá aceitar as novas conexões via socket novo, isto é, retornará um novo número de novo, isto é, retornará um novo número de socket socket para usar na comunicação de volta ao cliente. para usar na comunicação de volta ao cliente.

Page 26: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Accept()Accept() -cont. -cont.

int accept (int accept ( int sockfd, struct sockaddr *fromaddrptr, int *addresslen int sockfd, struct sockaddr *fromaddrptr, int *addresslen))

sockfdsockfd número do socket atribuído anteriormente. número do socket atribuído anteriormente.

*fromaddrptr*fromaddrptr estrutura que contém o endereço do cliente onde estrutura que contém o endereço do cliente onde enviar as respostas.enviar as respostas.

AddresslenAddresslen é o tamanho da estrutura de endereço.é o tamanho da estrutura de endereço.

Page 27: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Accept()Accept() -cont -cont

struct sockaddr_in other_app_addr;struct sockaddr_in other_app_addr;int sockid, newsockid, addrsize;int sockid, newsockid, addrsize;

addrsize = sizeof(other_app_addr));addrsize = sizeof(other_app_addr));newsockid = accept(sockid, (struct sockaddr *)newsockid = accept(sockid, (struct sockaddr *) &other_app_addr, &addrsize);&other_app_addr, &addrsize); /* newsockid to communicate with client, /* newsockid to communicate with client, sockid to accept more connections */sockid to accept more connections */

Page 28: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Enviando e recebendo dadosEnviando e recebendo dados

Os dados são enviados/recebidos usando chamadas Os dados são enviados/recebidos usando chamadas E/S do Unix ou chamadas de redeE/S do Unix ou chamadas de rede

send/recvsend/recv para socketspara socketswrite/readwrite/read para qualquer operação de I/Opara qualquer operação de I/O

Page 29: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

send()send()

int send (int send (int sockfd, char *buff, int bufflen, int sockfd, char *buff, int bufflen, int flagsint flags))

sockfdsockfd número do socket . número do socket . *buff*buff é o endereço do dado a ser enviado. O conteúdo abriga a é o endereço do dado a ser enviado. O conteúdo abriga a

mensagem.mensagem. bufflenbufflen é número de bytes a enviar. é número de bytes a enviar. flagsflags controla a transmissão. Para nós será sempre 0 (zero) . controla a transmissão. Para nós será sempre 0 (zero) .

Obs.: retorna o número de bytes efetivamente enviado. Obs.: retorna o número de bytes efetivamente enviado.

Page 30: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Exemplo: usando send()Exemplo: usando send()

char buffer[50];char buffer[50];struct sockaddr_in other_app_addr;struct sockaddr_in other_app_addr;int retcode int retcode

/* suppose we have done socket() and /* suppose we have done socket() and bind() calls, filled in other_app_addr,and bind() calls, filled in other_app_addr,and put 23 bytes of data into buffer */put 23 bytes of data into buffer */

retcode = send(sockfd, buffer, 23, 0)retcode = send(sockfd, buffer, 23, 0)

Page 31: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

recv() recv()

int recv (int recv (int sockfd, char *buff, int int sockfd, char *buff, int bufflen, int flagsbufflen, int flags))

sockfdsockfd é o número do socket obtido anteriormente. é o número do socket obtido anteriormente. *buff*buff é o endereço onde o dado será armazenado. é o endereço onde o dado será armazenado. bufflenbufflen número máximo esperado número máximo esperado flagsflags controla a recepção. Esse valor será sempre 0. controla a recepção. Esse valor será sempre 0.

Obs.: recv() retorna o número de bytes efetivamente recebidosObs.: recv() retorna o número de bytes efetivamente recebidos

Page 32: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Exemplo: usando recv()Exemplo: usando recv()

char buffer[50];char buffer[50];struct sockaddr_in other_app_addr;struct sockaddr_in other_app_addr;int nread, addrlen;int nread, addrlen;

/* suppose we have done socket(), bind() */ /* suppose we have done socket(), bind() */nread = recv(sockfd, buffer, 23, 0) nread = recv(sockfd, buffer, 23, 0)

Page 33: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Sockets - outras funçõesSockets - outras funções

Sockets - estruturasSockets - estruturas

Sockets - funçõesSockets - funções

Ordenação de bytes e conversõesOrdenação de bytes e conversões

Serviço não orientado a conexãoServiço não orientado a conexão

Page 34: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Sockets - estruturasSockets - estruturas

struct sockaddr {struct sockaddr { // estrutura parâmetro de connect()// estrutura parâmetro de connect()unsigned short sa_family; // AF_xxxunsigned short sa_family; // AF_xxx

char sa_data[14]; // IP + portachar sa_data[14]; // IP + porta

};};

Estrutura paralela para a Internet:Estrutura paralela para a Internet:struct sockaddr_in {struct sockaddr_in {

short int sin_family;short int sin_family;

unsigned short int sin_port;unsigned short int sin_port;

struct in_addr sin_addr;struct in_addr sin_addr;

unsigned char sin_zero[8]; // padunsigned char sin_zero[8]; // pad

};};

Page 35: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Sockets - estruturasSockets - estruturas

struct in_addr {struct in_addr {unsigned long s_addr;unsigned long s_addr;

}}

sin_port e sin_addr devem estar em Network byte sin_port e sin_addr devem estar em Network byte order. (htonorder. (htonxx()), isto é, colocar os bytes em ordem de ()), isto é, colocar os bytes em ordem de rede antes de mandá-los pela rede.rede antes de mandá-los pela rede. Motivo: são os campos enviados pela rede.Motivo: são os campos enviados pela rede.

Page 36: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Ordenação de bytes e conversõesOrdenação de bytes e conversões

Page 37: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Ordenação de BytesOrdenação de Bytes

Byte mais significanteByte mais significante chamado de chamado de Network byte orderNetwork byte order (NBO) (NBO) BigEndianBigEndian

Byte menos significanteByte menos significante chamado de chamado de Host byte orderHost byte order (HBO) (HBO) LittleEndianLittleEndian

Page 38: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Rotinas de Ordenação de ByteRotinas de Ordenação de Byte

Rotinas de ordenação de bytes: converte bytes de inteiros Rotinas de ordenação de bytes: converte bytes de inteiros para/de 16 e 32-bits de/para “Network Byte Order'' para/de 16 e 32-bits de/para “Network Byte Order'' números inteiros devem ser convertido explicitamente para/de números inteiros devem ser convertido explicitamente para/de

Network Byte OrderNetwork Byte Order.. computadores diferentes podem armazenar os bytes de inteiros em uma computadores diferentes podem armazenar os bytes de inteiros em uma

ordem diferente na memória.ordem diferente na memória. Network Byte Order é dita big-endianNetwork Byte Order é dita big-endian

Page 39: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Big Endian/Little EndianBig Endian/Little Endian

Page 40: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Sockets – funçõesSockets – funções

Se tivermos: Se tivermos: struct sockaddr_in ina;struct sockaddr_in ina; ina.sin_addr.s_addr = inet_addr(“132.241.5.10”);ina.sin_addr.s_addr = inet_addr(“132.241.5.10”);

inet_addr() retorna o endereço em NBO.inet_addr() retorna o endereço em NBO.

printf(printf(%s%s, inet_ntoa(ina.sin_addr));, inet_ntoa(ina.sin_addr)); Seqüência de código para aceitar conexões:Seqüência de código para aceitar conexões:

socket();socket(); bind();bind(); listen();listen(); accept();accept();

Page 41: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Procedures do UNIXProcedures do UNIX

htonlhtonl converte formato de host de 32 bit para nbo;converte formato de host de 32 bit para nbo;

ntohlntohl converte nbo para o formato host de 32 bit;converte nbo para o formato host de 32 bit;

htonshtons converte formato de host de 16 bit para nbo; converte formato de host de 16 bit para nbo;

ntohsntohs converte nbo para o formato host de 16 bit. converte nbo para o formato host de 16 bit.

Page 42: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Serviço não Orientado a ConexãoServiço não Orientado a Conexão

Page 43: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Serviço não orientado a conexãoServiço não orientado a conexão

Serviço de datagrama:Serviço de datagrama: o protocolo da camada de o protocolo da camada de transporte nãotransporte não garante a entrega do pacote; garante a entrega do pacote;

Não há identificação explícita de quem é o servidor e Não há identificação explícita de quem é o servidor e quem é o cliente;quem é o cliente;

Ao iniciar o contato com o outro lado precisamos Ao iniciar o contato com o outro lado precisamos saber:saber: o endereço IP;o endereço IP; número da porta onde contactar o outro lado. número da porta onde contactar o outro lado.

Ao esperar ser contactado pelo outro lado, precisa Ao esperar ser contactado pelo outro lado, precisa declarardeclarar número da porta que está esperando o outro ladonúmero da porta que está esperando o outro lado

Page 44: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

1.cria o descritor: socket()

2. atribui ao descritor um endereço: bind()

3. Aguarda pkt chegar: recvfrom()

4. Envia resposta(se houver): sendto()

5. Libera o descritor: close()

1. cria o descritor: socket()

2. Atribui ao descritor um endereço: (opcional) bind()

3. determina endereço do servidor

4. envia msg: sendto()

5. Aguarda chegada do pkt : recvfrom()

6. Libera o descritor: close()

CLIENTE

SERVIDOR

Page 45: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Exemplo: Servidor não orientado Exemplo: Servidor não orientado

#include <stdio.h>#include <stdio.h> #include <sys/types.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/inet.h> #include <errno.h> #include <errno.h> #define MY_PORT_ID 6090 /* numero > 5000 */ #define MY_PORT_ID 6090 /* numero > 5000 */ main() { main() { int sockid, nread, addrlen; int sockid, nread, addrlen; struct sockaddr_in my_addr, client_addr; struct sockaddr_in my_addr, client_addr; char msg[50]; char msg[50];

Page 46: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Exemplo: Servidor não orientado Exemplo: Servidor não orientado - cont.- cont.

printf("Servidor: criando o socket\n"); printf("Servidor: criando o socket\n"); if ( (sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ if ( (sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ printf("Servidor: erro no socket: %d\n",errno); printf("Servidor: erro no socket: %d\n",errno); exit(0); exit(0); } } printf("Servidor: Bindando socket local\n"); printf("Servidor: Bindando socket local\n");

bzero((char *) &my_addr, sizeof(my_addr)); bzero((char *) &my_addr, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET; my_addr.sin_addr.s_addr = htons(INADDR_ANY); my_addr.sin_addr.s_addr = htons(INADDR_ANY); my_addr.sin_port = htons(MY_PORT_ID); my_addr.sin_port = htons(MY_PORT_ID);

Page 47: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

if ( (bind(sockid, (struct sockaddr *) &my_addr,if ( (bind(sockid, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) ){sizeof(my_addr)) < 0) ){

printf("Servidor: falha no bindingprintf("Servidor: falha no binding: : %d\n",errno);%d\n",errno); exit(0);exit(0); } } printf("Servidor: iniciando bloqueio de mensagem printf("Servidor: iniciando bloqueio de mensagem

lida\n");lida\n"); nread = recvfrom(sockid,msg,11,0, nread = recvfrom(sockid,msg,11,0, (struct sockaddr *) &client_addr, &addrlen); (struct sockaddr *) &client_addr, &addrlen);

printf("Servidor: cod retorno lido éprintf("Servidor: cod retorno lido é %d\ %d\n",nread); n",nread);

if (nread >0) printf("Servidor: mensagem éif (nread >0) printf("Servidor: mensagem é: : %.11s\n",msg);%.11s\n",msg); close(sockid); close(sockid); }}

Exemplo: Servidor não orientadoExemplo: Servidor não orientado - cont.- cont.

Page 48: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Exemplo: Cliente não orientadoExemplo: Cliente não orientado

#include <stdio.h>#include <stdio.h> #include <sys/types.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/inet.h> #include <errno.h> #include <errno.h> #define MY_PORT_ID 6089 #define MY_PORT_ID 6089 #define SERVER_PORT_ID 6090 #define SERVER_PORT_ID 6090 #define SERV_HOST_ADDR "128.119.40.186" #define SERV_HOST_ADDR "128.119.40.186" main() { main() { int sockid, retcode; int sockid, retcode; struct sockaddr_in my_addr, server_addr; struct sockaddr_in my_addr, server_addr; char msg[12]; char msg[12];

Page 49: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

printf("Cliente: criando socket\n"); printf("Cliente: criando socket\n"); if ((sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ if ((sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ printf("Cliente: falha no socket: %d\n",errno); printf("Cliente: falha no socket: %d\n",errno); exit(0);exit(0); }} printf("Cliente: amarrando socket local\n");printf("Cliente: amarrando socket local\n"); bzero((char *) &my_addr, sizeof(my_addr));bzero((char *) &my_addr, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET; my_addr.sin_addr.s_addr = htonl(INADDR_ANY); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); my_addr.sin_port = htons(MY_PORT_ID); my_addr.sin_port = htons(MY_PORT_ID); if ( ( bind(sockid, (struct sockaddr *) &my_addr, if ( ( bind(sockid, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) ){sizeof(my_addr)) < 0) ){ printf("Cliente: falha no bindprintf("Cliente: falha no bind: %d\n",errno);: %d\n",errno); exit(0); exit(0); } }

Exemplo: Cliente não orientado - cont.

Page 50: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Printf("Cliente: criando estrutura addr para Printf("Cliente: criando estrutura addr para o servidor\n");o servidor\n"); bzero((char *) &server_addr, sizeof(server_addr)); bzero((char *) &server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = server_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); inet_addr(SERV_HOST_ADDR); server_addr.sin_port = htons(SERVER_PORT_ID); server_addr.sin_port = htons(SERVER_PORT_ID); printf("Cliente: iniciando mensagem eprintf("Cliente: iniciando mensagem e enviando\n"); enviando\n"); sprintf(msg, “sprintf(msg, “Ola para todos"); Ola para todos"); retcode = sendto(sockid,msg,12,0,(struct retcode = sendto(sockid,msg,12,0,(struct sockaddr *)&server_addr, sockaddr *)&server_addr, sizeof(server_addr)); sizeof(server_addr)); if (retcode <= -1){ if (retcode <= -1){ printf("cliente: falha no sendto: %d\n",errno); printf("cliente: falha no sendto: %d\n",errno); exit(0);exit(0); } } /* close socket */ /* close socket */ close(sockid); close(sockid); } }

Page 51: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Resumo do FluxogramaResumo do Fluxograma TCP / UDPTCP / UDP

Page 52: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV
Page 53: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Uma aplicação de tempo simples:Uma aplicação de tempo simples:

Cliente: Cliente: conecta ao servidorconecta ao servidor envia ao servidor a sua hora localenvia ao servidor a sua hora local lê de volta a hora do servidorlê de volta a hora do servidor

Servidor: Servidor: recebe conexões dos clientesrecebe conexões dos clientes imprime a hora local do clienteimprime a hora local do cliente envia ao cliente a sua hora localenvia ao cliente a sua hora local

Page 54: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Uma aplicação de tempo simples: código Uma aplicação de tempo simples: código clientecliente

1 #include <sys/types.h>1 #include <sys/types.h>2 #include <sys/socket.h>2 #include <sys/socket.h>3 #include <netinet/in.h>3 #include <netinet/in.h>4 #include <arpa/inet.h>4 #include <arpa/inet.h>5 #include <time.h>5 #include <time.h>6 #include <errno.h>6 #include <errno.h>7 #define SERV_HOST_ADDR "128.119.40.186" 7 #define SERV_HOST_ADDR "128.119.40.186" /* Don's host machine *//* Don's host machine */

8 main()8 main()9 {9 {10 int sockid;10 int sockid;11 struct sockaddr_in ssock_addr;11 struct sockaddr_in ssock_addr;12 struct timeval tp;12 struct timeval tp;13 struct timezone tzp;13 struct timezone tzp;

Page 55: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

15 15 /* create a socket *//* create a socket */16 if ((sockid = socket(16 if ((sockid = socket(AF_INET,SOCK_STREAM, AF_INET,SOCK_STREAM, 00)) < 0){)) < 0){

17 printf("erro criacao=%d",errno);17 printf("erro criacao=%d",errno);18 exit(0); 18 exit(0); 19 }19 }202021 printf("Criando struct addr p/ server…");21 printf("Criando struct addr p/ server…");22 bzero((char *) &server_addr, 22 bzero((char *) &server_addr,

sizeof(server_addr)); sizeof(server_addr)); 23 server_addr.sin_family = AF_INET; 23 server_addr.sin_family = AF_INET; 24 server_addr.sin_addr.s_addr = 24 server_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); inet_addr(SERV_HOST_ADDR); 25 server_addr.sin_port = htons(SERVER_PORT_ID); 25 server_addr.sin_port = htons(SERVER_PORT_ID); 26 if (connect(sockid, (struct sockaddr *) 26 if (connect(sockid, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0){&server_addr, sizeof(server_addr)) < 0){27 printf("error connecting to server, error: 27 printf("error connecting to server, error: %d %d \n\n",errno); ",errno);

28 exit(0);28 exit(0);29 }29 }

Page 56: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

30 /* send time of day */30 /* send time of day */31 gettimeofday(&tp,&tzp);31 gettimeofday(&tp,&tzp);32 /* convert from host byte order to 32 /* convert from host byte order to network network

byte order */byte order */33 printf("client: local time is %ld 33 printf("client: local time is %ld \\nn",tp.tv_sec);",tp.tv_sec);

34 tp.tv_sec = htonl(tp.tv_sec);34 tp.tv_sec = htonl(tp.tv_sec);35 tp.tv_usec = htonl(tp.tv_usec);35 tp.tv_usec = htonl(tp.tv_usec);38 /* send time of day to other side */38 /* send time of day to other side */39 write(sockid, &tp, sizeof(tp));39 write(sockid, &tp, sizeof(tp));40 /* get time of day back fro other 40 /* get time of day back fro other side and display */side and display */

41 if ( (read(sockid, &tp, sizeof(tp))) 41 if ( (read(sockid, &tp, sizeof(tp))) < 0){< 0){

42 printf("error reading new socket 42 printf("error reading new socket \n\n"); ");

43 exit(0); 43 exit(0); 44 }44 }4545

Page 57: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

46 /* convert from network byte order to 46 /* convert from network byte order to host byte order */host byte order */47 tp.tv_sec = ntohl(tp.tv_sec);47 tp.tv_sec = ntohl(tp.tv_sec);48 tp.tv_usec = ntohl(tp.tv_usec);48 tp.tv_usec = ntohl(tp.tv_usec);49 printf("client: remote time is %ld 49 printf("client: remote time is %ld \\nn",tp.tv_sec);",tp.tv_sec);50 close(sockid); 50 close(sockid); 51 }51 }

Page 58: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

Aplicação de tempo: código servidorAplicação de tempo: código servidor

1 #include <stdio.h>1 #include <stdio.h>2 #include <sys/types.h>2 #include <sys/types.h>3 #include <sys/socket.h>3 #include <sys/socket.h>4 #include <netinet/in.h>4 #include <netinet/in.h>5 #include <arpa/inet.h>5 #include <arpa/inet.h>6 #include <time.h>6 #include <time.h>7 #include <errno.h>7 #include <errno.h>8 #define MY_PORT_ID 60908 #define MY_PORT_ID 60909910 main()10 main()11 {11 {12 int sockid, newsockid, i,j;12 int sockid, newsockid, i,j;13 struct sockaddr_in ssock_addr;13 struct sockaddr_in ssock_addr;14 struct timeval tp;14 struct timeval tp;15 struct timezone tzp;15 struct timezone tzp;

Page 59: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

17 if ( (sockid = socket (AF_INET, 17 if ( (sockid = socket (AF_INET, SOCK_STREAM, 0)) < 0)SOCK_STREAM, 0)) < 0)

18 { printf("erro criacao18 { printf("erro criacao= = %d %d \n\n"",errno); ,errno); exit(0);} /* man errno */exit(0);} /* man errno */

19 /* name the socket using wildcards */19 /* name the socket using wildcards */20 bzero((char *) &ssock_addr, 20 bzero((char *) &ssock_addr,

sizeof(ssock_addr));sizeof(ssock_addr));21 ssock_addr.sin_family = AF_INET;21 ssock_addr.sin_family = AF_INET;22 ssock_addr.sin_addr.s_addr = 22 ssock_addr.sin_addr.s_addr =

htonl(INADDR_ANY);htonl(INADDR_ANY);23 ssock_addr.sin_port = htons(MY_PORT_ID);23 ssock_addr.sin_port = htons(MY_PORT_ID);24 /* bind the socket to port address */24 /* bind the socket to port address */25 if ( ( bind(sockid, (struct sockaddr *) 25 if ( ( bind(sockid, (struct sockaddr *)

&ssock_addr,sizeof(ssock_addr))< 0))&ssock_addr,sizeof(ssock_addr))< 0))26 { printf("error binding socket, error: 26 { printf("error binding socket, error:

%d %d \n",errno); exit(0); } ",errno); exit(0); } 29 /* start accepting connections */ 29 /* start accepting connections */ 30 if ( listen (sockid, 5) < 0)30 if ( listen (sockid, 5) < 0)31 { printf("erro listening: %d 31 { printf("erro listening: %d \n\n",errno); ",errno);

exit(0); }exit(0); }

Page 60: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

33 for (i=1; i<=50000 ;i++) {33 for (i=1; i<=50000 ;i++) {34 /* accept a connection */34 /* accept a connection */35 newsockid = accept(sockid, (struct 35 newsockid = accept(sockid, (struct

sockaddr *)0, (int *)0);sockaddr *)0, (int *)0);36 if (newsockid < 0)36 if (newsockid < 0)37 { printf("error accepting socket, 37 { printf("error accepting socket,

error: %d error: %d \n",errno); ",errno); exit(0); }exit(0); }

38 /* le tempo remoto */38 /* le tempo remoto */39 if ( (read(newsockid, &tp, 39 if ( (read(newsockid, &tp,

sizeof(tp))) < 0)sizeof(tp))) < 0)40 { printf("error reading new socket 40 { printf("error reading new socket

\n"); exit(0); }"); exit(0); }41 /* convert from network byte order to 41 /* convert from network byte order to

host byte order */host byte order */42 tp.tv_sec = ntohl(tp.tv_sec);42 tp.tv_sec = ntohl(tp.tv_sec);43 tp.tv_usec = ntohl(tp.tv_usec);43 tp.tv_usec = ntohl(tp.tv_usec);44 printf("server: remote time is 44 printf("server: remote time is

%ld %ld \n",tp.tv_sec);",tp.tv_sec);

Page 61: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

46 /* get local time of day and send to 46 /* get local time of day and send to client*/client*/

47 for (j=0; j<1000000; j++);47 for (j=0; j<1000000; j++);48 /* delay */48 /* delay */49 gettimeofday(&tp,&tzp);49 gettimeofday(&tp,&tzp);50 /* convert from host byte order to 50 /* convert from host byte order to

network byte order */network byte order */51 printf("server: local time is 51 printf("server: local time is

%ld %ld \n",tp.tv_sec);",tp.tv_sec);52 tp.tv_sec = htonl(tp.tv_sec);52 tp.tv_sec = htonl(tp.tv_sec);53 tp.tv_usec = htonl(tp.tv_usec);53 tp.tv_usec = htonl(tp.tv_usec);54 write(newsockid, &tp, sizeof(tp));54 write(newsockid, &tp, sizeof(tp));55 close(newsockid);55 close(newsockid);56 }56 }57 close(sockid);57 close(sockid);58 }58 }

Page 62: Comunicação entre processos usando Sockets  Disciplina: Linguagem de Programação IV

BibliografiaBibliografia

COMER, Douglas E. InternetWorking with TCP/IP -VOL COMER, Douglas E. InternetWorking with TCP/IP -VOL 1. 1.

Tutorial sobre sockets: http://beej.us/guide/bgnet/Tutorial sobre sockets: http://beej.us/guide/bgnet/ http://www.newdevices.com/tutoriales/index.htmlhttp://www.newdevices.com/tutoriales/index.html

Sockets em Java: http://www.javasoft.com/docs/books/tutorial/networking/sockets/

definition.html