Escolar Documentos
Profissional Documentos
Cultura Documentos
disponvel em muitos sistemas operacionais ex: Windows NT, Unix, etc. Facilita a Programao Torna as aplicaes mais flexveis
Reviso Sockets
O que um Socket?
Socket uma ponta de uma comunicao ponto-a-ponto entre dois programas rodando em uma rede.
A API SOCKET
A API SOCKET
Endereamento na Internet
Endereamento na Internet
servidor de nomes:
as funes de usurio gethostbyname() e gethostbyaddress() contactam o servidor de nome local atravs da porta 53 o servidor de nomes retorna um endereo IP do nome da mquina solicitada
Criando um socket
Mesmo ponto comum (socket) usado para enviar/receber
dados
no existe, a priori, associao do socket com a rede
Exemplo:
#include <sys/types.h> #include <sys/socket.h> int sockfd; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { /* handle error */ }
O S.O. sabe que as messagens recebidas naquele endereo e porta devem ser entregues para o socket. Endereo de portas. Ver arquivos /etc/services.
bit
A chamada ao bind()
int bind ( int sockfd, struct sockaddr *myaddr, int addresslen)
sockfd: o nmero do socket obtido anteriormente. *myaddr: especifica o end. local associado ao
Obs.: se a funo retornar um erro ento o nmero da porta j est em uso ou fora do limite.
SERVIDOR
Cria o descritor: socket() para receber pedidos Atribui um endereo ao descritor:bind() Avisa que est aceitando conexes: listen() bloquea/espera novas conexes.: accept()(novos sockets criados na volta)
Troca de msg
CLIENTE
cria o descritor: socket() Atribui ao descritor um endereo (opcional) :bind()
espera pelo pkt:recv() envia resposta:send() Libera o descritor: close() espera a resp:recv() Libera o descritor: close()
aperto de mo cliente/servidor:
cliente deve se conectar ao servidor antes de enviar ou receber dados cliente no passar do connect() at o servidor aceit-lo servidor deve aceitar o cliente antes de enviar ou receber dados servidor no passar do accept() at o cliente usar connect()
cliente usa connect() para requisitar conexo junto ao servidor protocolo da camada de transporte (ex: TCP) inicia
procedimento para conexo atravs do aperto de mo cliente/servidor connect() retorna quando o servidor aceita a conexo ou time-out (no h resposta) usado com protocolos confiveis, mas tambm com datagramas
sockfd: nmero do socket atribudo anteriormente. Os processos o usam para enviar conexes aceitas.
*toaddrptr: especifica o end. Remoto (inclusive a porta). Addresslen : o tamanho da estrutura de endereo.
A chamada listen()
Usado por servidores orientados a conexo. avisa a rede/S.O. que o servidor aceitar requisies para conexo. No bloqueia e no espera por requisies!
int listen ( int sockfd, int maxwaiting)
sockfd: nmero do socket atribudo anteriormente. maxwaiting: nmero mximo de conexes que podem ser enfileiradas, enquanto aguardam o servidor executar um accept(). O valor tpico 5.
Accept() -cont.
int accept ( int sockfd, struct sockaddr *fromaddrptr, int *addresslen)
Accept() -cont
struct sockaddr_in other_app_addr; int sockid, newsockid, addrsize; addrsize = sizeof(other_app_addr)); newsockid = accept(sockid, (struct sockaddr *) &other_app_addr, &addrsize); /* newsockid to communicate with client, sockid to accept more connections */
send()
int send (int sockfd, char *buff, int bufflen, int flags)
sockfd nmero do socket . *buff o endereo do dado a ser enviado. O contedo abriga a
mensagem. bufflen nmero de bytes a enviar. flags controla a transmisso. Para ns ser sempre 0 (zero) . Obs.: retorna o nmero de bytes efetivamente enviado.
recv()
int recv (int sockfd, char *buff, int bufflen, int flags)
sockfd o nmero do socket obtido anteriormente. *buff o endereo onde o dado ser armazenado. bufflen nmero mximo esperado flags controla a recepo. Esse valor ser sempre 0.
Sockets - estruturas
struct sockaddr { // estrutura parmetro de connect()
};
};
Sockets - estruturas
struct in_addr {
unsigned long s_addr;
order. (htonx()), isto , colocar os bytes em ordem de rede antes de mand-los pela rede.
Motivo: so os campos enviados pela rede.
Ordenao de Bytes
Byte mais significante
chamado de Network byte order (NBO) BigEndian
Sockets funes
Se tivermos: struct sockaddr_in ina; ina.sin_addr.s_addr = inet_addr(132.241.5.10);
inet_addr() retorna o endereo em NBO.
printf(%s, inet_ntoa(ina.sin_addr));
Seqncia de cdigo para aceitar conexes:
socket(); bind(); listen(); accept();
Procedures do UNIX
transporte no garante a entrega do pacote; No h identificao explcita de quem o servidor e quem o cliente; Ao iniciar o contato com o outro lado precisamos saber:
o endereo IP; nmero da porta onde contactar o outro lado.
declarar
nmero da porta que est esperando o outro lado
SERVIDOR 1.cria o descritor: socket() 2. atribui ao descritor um endereo: bind() 3. Aguarda pkt chegar: recvfrom() 4. Envia resposta(se houver): sendto()
%d\n",nread);
if (nread >0) printf("Servidor: mensagem : %.11s\n",msg); close(sockid); }
Printf("Cliente: criando estrutura addr para o servidor\n"); bzero((char *) &server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); server_addr.sin_port = htons(SERVER_PORT_ID);
printf("Cliente: iniciando mensagem e enviando\n"); sprintf(msg, Ola para todos"); retcode = sendto(sockid,msg,12,0,(struct sockaddr *)&server_addr, sizeof(server_addr)); if (retcode <= -1){ printf("cliente: falha no sendto: %d\n",errno); exit(0); } /* close socket */ close(sockid); }
Servidor:
recebe conexes dos clientes imprime a hora local do cliente envia ao cliente a sua hora local
15 16
/* create a socket */
if ((sockid = socket(AF_INET,SOCK_STREAM, 0)) < 0){ 17 printf("erro criacao=%d",errno); 18 exit(0); 19 } 20 21 printf("Criando struct addr p/ server"); 22 bzero((char *) &server_addr, sizeof(server_addr)); 23 server_addr.sin_family = AF_INET; 24 server_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); 25 server_addr.sin_port = htons(SERVER_PORT_ID); 26 if (connect(sockid, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0){ 27 printf("error connecting to server, error: %d \n",errno); 28 exit(0);
30 /* send time of day */ 31 gettimeofday(&tp,&tzp); 32 /* convert from host byte order to network byte order */ 33 printf("client: local time is %ld \n",tp.tv_sec); 34 tp.tv_sec = htonl(tp.tv_sec); 35 tp.tv_usec = htonl(tp.tv_usec); 38 /* send time of day to other side */ 39 write(sockid, &tp, sizeof(tp)); 40 /* get time of day back fro other side and display */ 41 if ( (read(sockid, &tp, sizeof(tp))) < 0){ 42 printf("error reading new socket \n"); 43 exit(0); 44 } 45
46 /* convert from network byte order to host byte order */ 47 tp.tv_sec = ntohl(tp.tv_sec); 48 tp.tv_usec = ntohl(tp.tv_usec); 49 printf("client: remote time is %ld \n",tp.tv_sec); 50 close(sockid); 51 }
17 18 19 20 21 22
23 24 25 26
29 30 31
if ( (sockid = socket (AF_INET, SOCK_STREAM, 0)) < 0) { printf("erro criacao= %d \n",errno); exit(0);} /* man errno */ /* name the socket using wildcards */ bzero((char *) &ssock_addr, sizeof(ssock_addr)); ssock_addr.sin_family = AF_INET; ssock_addr.sin_addr.s_addr = htonl(INADDR_ANY); ssock_addr.sin_port = htons(MY_PORT_ID); /* bind the socket to port address */ if ( ( bind(sockid, (struct sockaddr *) &ssock_addr,sizeof(ssock_addr))< 0)) { printf("error binding socket, error: %d \n",errno); exit(0); } /* start accepting connections */ if ( listen (sockid, 5) < 0) { printf("erro listening: %d \n",errno); exit(0); }
33 34 35 36 37 38 39 40
41
42 43 44
for (i=1; i<=50000 ;i++) { /* accept a connection */ newsockid = accept(sockid, (struct sockaddr *)0, (int *)0); if (newsockid < 0) { printf("error accepting socket, error: %d \n",errno); exit(0); } /* le tempo remoto */ if ( (read(newsockid, &tp, sizeof(tp))) < 0) { printf("error reading new socket \n"); exit(0); } /* convert from network byte order to host byte order */ tp.tv_sec = ntohl(tp.tv_sec); tp.tv_usec = ntohl(tp.tv_usec); printf("server: remote time is %ld \n",tp.tv_sec);
46 /* get local time of day and send to client*/ 47 for (j=0; j<1000000; j++); 48 /* delay */ 49 gettimeofday(&tp,&tzp); 50 /* convert from host byte order to network byte order */ 51 printf("server: local time is %ld \n",tp.tv_sec); 52 tp.tv_sec = htonl(tp.tv_sec); 53 tp.tv_usec = htonl(tp.tv_usec); 54 write(newsockid, &tp, sizeof(tp)); 55 close(newsockid); 56 } 57 close(sockid); 58 }
Bibliografia
COMER, Douglas E. InternetWorking with TCP/IP -VOL
1.
Sockets em Java:
http://www.javasoft.com/docs/books/tutorial/networking/sockets/d efinition.html