aula 12 - sockets

25
Redes de Computadores Linguagem de Programação Sockets Ms. Marcello Erick Bonfim [email protected]

Upload: jeancarlos84

Post on 10-Apr-2015

5.205 views

Category:

Documents


0 download

DESCRIPTION

Material sobre sockets da API Berkeley

TRANSCRIPT

Page 1: Aula 12 - Sockets

Redes de Computadores

Linguagem de Programação

Sockets

Ms. Marcello Erick [email protected]

Page 2: Aula 12 - Sockets

O que são e para que servem os sockets? Os sockets são os programas responsáveis pela

comunicação ou interligação de outros programas na internet.

Quando você se conecta a um serviço qualquer você está usando um socket, no caso chama-se a rotina socket() como cliente de um lado, e do lado do host com serviço, uma rotina de socket servidor.

Existem alguns tipos de sockets. Trabalharemos com os "Stream Sockets“, também conhecido como "SOCK_STREAM".

Stream Sockets usam TCP, e são usados em diversas aplicações como telnet, www, etc. Os pacotes são seqüenciais, seguem em 2 vias, sendo possível ler e gravar.

Page 3: Aula 12 - Sockets

API Socket API = Application Program Interface:

API é o elemento de ligação entre a aplicação e um sistema de mais baixo nível.

Consiste de algumas funções bem definidas que podem ser usadas pelo usuário na sua aplicação.

Page 4: Aula 12 - Sockets

Socket: como funciona?

Page 5: Aula 12 - Sockets

Bibliotecas (headers)

Existem alguns headers usados em conjunto para facilitar ao máximo a programação de sockets. #include <sys/types.h> #include <sys/sockets.h> #include <netinet/in.h> #include <netdb.h>

Page 6: Aula 12 - Sockets

Declarando um socket

Para se declarar um socket não existe segredo. Ele é do tipo int e declara-se normalmente:

1. main(){2. int Meusocket;3. ...4. }

Page 7: Aula 12 - Sockets

Definindo uma estrutura Os dados necessários do host a que se quer comunicar, são definidos

através de uma struct. A struct usada para conexões na internet é a sockaddr_in, e possui a seguinte declaração:

struct sockaddr_in { short int sin_family; /* Familia do endereco */ unsigned short int sin_port; /* Numero da porta */ struct in_addr sin_addr; /* IP do Host */ unsigned char sin_zero[8]; /* Zera a estrutura, algum espaco como struct sockaddr */ }

sin_family usa a seguinte sintaxe: + AF_INET (ARPA INTERNET PROTOCOLS) - "A mais usada" + AF_UNIX (UNIX INTERNET PROTOCOLS) + AF_ISO (ISO PROTOCOLS) + AF_NS (XEROX NETWORK SYSTEM PROTOCOLS)

main(){ int Meusocket; struct sockaddr_in endereco; .. }

Page 8: Aula 12 - Sockets

Construindo um socket A construção de um socket segue o modelo:

Meusocket = socket(sin_family, tipo_do_socket_desejado,Numero_protocolo);

Onde: sin_family são essas já explicadas; tipo_do_socket_desejado, no caso SOCK_STREAM ou

SOCK_DGRAM; Numero_protocolo é o número correspondente do protocolo

que se vai trabalhar,ex: 0 - IP - INTERNET PROTOCOL 1 - ICMP - INTERNET CONTROL MESSAGE PROTOCOL 2 - IGMP - INTERNET GROUP MULTICAST PROTOCOL 3 - GGP - GATEWAY-GATEWAY PROTOCOL 6 - TCP - TRANSMISSION CONTROL PROTOCOL 17 - UDP - USER DATAGRAMA PROTOCOL

Page 9: Aula 12 - Sockets

Um exemplo prático seria:1. main(){2. int Meusocket; /* Declarando a variável socket */3. ..4. Meusocket = socket(AF_INET,SOCK_STREAM,0);5. ..6. }

Page 10: Aula 12 - Sockets

Serviço com conexão (TCP)

Page 11: Aula 12 - Sockets

Função Bind (Associação) Um processo servidor precisa associar um socket a um endereço IP e

uma porta, para avisar o sistema operacional que deseja receber dados que chegam ao host.

bind(Meusocket,(struct sockaddr *)&local,sizeof(struct sockaddr))

Page 12: Aula 12 - Sockets

Sintaxe: int bind(int Meusocket, struct sockaddr *local, int addrlen);

1. /* Headers */2. #include <string.h>3. #include <sys/types.h>4. #include <sys/socket.h>

5. #define MINHA_PORTA 200006. main(){7. int Meusocket;8. struct sockaddr_in meu_endereco;

9. Meusocket = socket (AF_INET,SOCK_STREAM,0);10. local.sin_family = AF_INET;11. local.sin_port = htons(MINHA_PORTA);12. local.sin_addr.s_addr = inet_addr("200.100.100.1");

13. bind(Meusocket,(struct sockaddr *)&local,sizeof(struct sockaddr));14. ...15. }

Page 13: Aula 12 - Sockets

Função listen() Para colocar um socket em modo escuta

(servidor) usamos a chamada de sistema listen(): #include <sys/socket.h> int listen( int sockfd, int backlog );

Parâmetros: sockfd: descritor do socket. backlog: Número máximo de conexões

pendentes (fila de conexões para serem atendidas em seqüência).

Retorna 0 em caso de sucesso.

Page 14: Aula 12 - Sockets

Função accept() Função responsável por aceitar uma

conexão num socket. Um socket cliente pede permissão para um socket servidor para ambos se comunicarem,essa função será a que decidirá o futuro da conexão, se aceita ou rejeita. #include <sys/socket.h> int accept( int sockfd, struct sockaddr *

claddr, socklen_t * len );

Page 15: Aula 12 - Sockets

Parâmetros Accept() sockfd – o descritor do socket. claddr – a estrutura onde será guardado o

endereço do cliente. len – argumento valor/resultado com o

tamanho da estrutura do endereço. Retorno:

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.

Page 16: Aula 12 - Sockets

Função connect()

Essa função,como o próprio nome diz, é a função responsável pela conexão do socket cliente com um serviço servidor qualquer. int connect(Meusocket,(struct sockaddr

*) &client, sizeof(endereço));

Page 17: Aula 12 - Sockets

As Funções send() e recv() A função send() é usada para enviar uma mensagem para um socket. A função recv() é usada para receber dados em um socket. Similares as funções read() e write() do Unix.

int send(int Meusocket, const void *msg, size_t len, int flags);

onde: Meusocket -> é o bom e velho arquivo socket, nosso velho

conhecido. *msg -> é um ponteiro p/ a mensagem que queremos enviar. len -> é o tamanho da mensagem.Se a mensagem é muito grande

para passar atomicamente sobre o protocolo escolhido, a mensagem de erro EMSGSIZE é retornada, e a mensagem não é transmitida.

flags -> São parâmetros adicionais,podem ser: #define MSG_OOB 0x1 /* processa dados out-of-band */ #define MSG_DONTROUTE 0x4 /* debuga */

send(Novosocket, "Seja bem vindo!\n", 16, 0)

Page 18: Aula 12 - Sockets

int recv(int Meusocket, void *buf, int len, unsigned int flags);

onde: Meusocket -> é o socket para ler de outro,no caso, um

socket local. buf -> Aqui é o endereço da área do buffer. len -> é o tamanho do buffer. + flags -> são formados por MSG_OOB e MSG_PEEK

permitindo receber dados out-of-band e permitindo espiar dados que entram. Esta chamada deve ser usada somente com sockets do tipoSOCK_STREAM.

recv(Meusocket, buf, MAXDATASIZE, 0)

Page 19: Aula 12 - Sockets

Exemplo servidor: servidor.c1. #include<sys/types.h>2. #include<sys/socket.h>3. #include<netinet/in.h>4. #include<unistd.h>5. #include<stdlib.h>6. #include<stdio.h>

7. main()8. {9. int cont,create_socket,new_socket,addrlen,tempo;10. int bufsize = 128;11. char *buffer = malloc(bufsize);12. struct sockaddr_in address;13. 14. if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)15. printf("Socket criado!!!\n");16. address.sin_family = AF_INET;17. address.sin_addr.s_addr = INADDR_ANY;18. address.sin_port = htons(15000);

Page 20: Aula 12 - Sockets

Continuação: servidor.c1. if (bind(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)2. printf("Escutando...\n");3. listen(create_socket,3);4. addrlen = sizeof(struct sockaddr_in);5. new_socket = accept(create_socket,(struct sockaddr

*)&address,&addrlen);6. if (new_socket > 0){7. printf("O cliente %s esta conectado...\n",inet_ntoa(address.sin_addr));8. for(cont=1;cont<5000;cont++)9. printf("\x7");10. } 11. recv(new_socket,buffer,bufsize,0);12. tempo=atoi(buffer);13. sleep(tempo);14. strcpy (buffer,"Acorde ja se passaram os segundos desejados");15. send(new_socket,buffer,bufsize,0);16. close(new_socket);17. close(create_socket);18. }

Page 21: Aula 12 - Sockets

Exemplo cliente: cliente.c1. #include<sys/socket.h>2. #include<sys/types.h>3. #include<netinet/in.h>4. #include<unistd.h>5. #include<stdlib.h>6. #include<stdio.h>

7. main(int argc,char *argv[])8. {9. int create_socket;10. int bufsize = 128;11. char *buffer = malloc(bufsize);12. struct sockaddr_in address;13. 14. if (argc<=3)15. {16. printf ("use assim: ./%s ip_servidor SET x , onde x e o tempo em segundos!!!\

n",argv[0]);17. exit (0);18. }

Page 22: Aula 12 - Sockets

Continuação: cliente.c1. else2. strcpy(buffer,argv[2]);3. if (strcmp(buffer,"SET")==0)4. strcpy(buffer,argv[3]);5. else6. {7. printf ("sua sintaxe contem erro!!!\n");8. exit (0);9. }10. if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)11. printf("Socket criado!!!\n");12. address.sin_family = AF_INET;13. address.sin_port = htons(15000);14. inet_pton(AF_INET,argv[1],&address.sin_addr);15. 16. if (connect(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)17. printf("A conexao foi aceita com o servidor %s...\n",inet_ntoa(address.sin_addr));18. send(create_socket,buffer,bufsize,0);19. recv(create_socket,buffer,bufsize,0);20. printf ("%s\n",buffer);21. close(create_socket);22. }

Page 23: Aula 12 - Sockets

Resumindo: No servidor:

bind(create_socket,(struct sockaddr *)&address, sizeof(address));

listen(create_socket,3); accept(create_socket,(struct sockaddr *)

&address,&addrlen); send(new_socket,buffer,bufsize,0); recv(new_socket,buffer,bufsize,0).

No cliente: connect(create_socket,(struct sockaddr

*)&address,sizeof(address); send(new_socket,buffer,bufsize,0) e

recv(new_socket,buffer,bufsize,0).

Page 24: Aula 12 - Sockets

Serviço com conexão (TCP)

Page 25: Aula 12 - Sockets

Referências

Comer, D. E. Redes de Computadores e Internet, Quarta Edição, 2007.

Mariz, D. A Camada de Transporte Socket, 2004.