Sockets André Restivo Faculdade de Engenharia da Universidade do Porto April 29, 2013 André Restivo (FEUP) Sockets April 29, 2013 1 / 27 Sumário 1 Introdução 2 Cliente/Servidor 3 API C++ 4 Exemplo André Restivo (FEUP) Sockets April 29, 2013 2 / 27 Introdução Outline 1 Introdução 2 Cliente/Servidor 3 API C++ 4 Exemplo André Restivo (FEUP) Sockets April 29, 2013 3 / 27 Introdução Sockets em C++ Os sockets são um protocolo independente que permite a criação de ligações entre processos. Os sockets podem ser: baseados em conexões ou sem conexão: Existe uma conexão estabelecida antes da comunicação ou cada pacote indica o seu destino? baseados em pacotes ou streams: As mensagens têm um tamanho ou são um fluxo contínuo de dados? com ou sem garantia de entrega: As mensagens podem ser perdidas, duplicadas, reordenadas ou corrompidas? André Restivo (FEUP) Sockets April 29, 2013 4 / 27 Introdução Características Um socket é caracterizado pelo seu domínio, tipo e protocolo. Domínios comuns são: AF_UNIX: UNIX pathname AF_INET: host and port number Tipos comuns são: circuito virtual: dados recebidos pelo ordem correta e com garantia de entrega. datagrama: ordem aleatória e sem garantia de entrega. André Restivo (FEUP) Sockets April 29, 2013 5 / 27 Introdução Protocolos Cada tipo de socket tem um ou mais protocolos possíveis: TCP/IP (circuitos virtuais) UDP (datagramas) Utilização de sockets: Baseados em conexões para ligações cliente/servidor em que o servidor fica à espera de uma ligação do cliente. Sem conexão para ligações P2P em que os processos são simétricos. André Restivo (FEUP) Sockets April 29, 2013 6 / 27 Cliente/Servidor Outline 1 Introdução 2 Cliente/Servidor 3 API C++ 4 Exemplo André Restivo (FEUP) Sockets April 29, 2013 7 / 27 Cliente/Servidor Comunicação: Servidor O servidor realiza as seguintes acções: socket: create the socket bind: give the address of the socket on the server listen: specifies the maximum number of connection requests that can be pending for this process accept: establish the connection with a specific client send,recv: stream-based equivalents of read and write (repeated) shutdown: end reading or writing close: release kernel data structures André Restivo (FEUP) Sockets April 29, 2013 8 / 27 Cliente/Servidor Comunicação: Cliente O cliente realiza as seguintes acções: socket: create the socket connect: connect to a server send,recv: (repeated) shutdown close André Restivo (FEUP) Sockets April 29, 2013 9 / 27 API C++ Outline 1 Introdução 2 Cliente/Servidor 3 API C++ 4 Exemplo André Restivo (FEUP) Sockets April 29, 2013 10 / 27 API C++ socket Exemplo #i n c l u d e <s y s / t y p e s . h> #i n c l u d e <s y s / s o c k e t . h> i n t s o c k e t ( i n t domain , i n t t y p e , i n t p r o t o c o l ) ; Retorna um descritor de ficheiro (file descriptor) ou -1 se falhar O domínio é normalmente AF_INET. type pode ser: SOCK STREAM: Circuito virtual SOCK DGRAM: Datagrama protocol é normalmente 0. André Restivo (FEUP) Sockets April 29, 2013 11 / 27 API C++ bind Exemplo #i n c l u d e <s y s / t y p e s . h> #i n c l u d e <s y s / s o c k e t . h> i n t b i n d ( i n t s o c k f d , s t r u c t s o c k a d d r ∗my_addr , i n t a d d r l e n ) ; sid: é o socket id (file descriptor devolvido bind). addrPtr: um apontador para a estrutura do endereço (depende do tipo de ligação). len: o tamanho de *addrPtr Associa um socket id com um endereço de forma a que outros processos se possam ligar. No caso de usarmos IP (internet protocol) o endereço é da forma endereço IP + porta. André Restivo (FEUP) Sockets April 29, 2013 12 / 27 API C++ connect Exemplo #i n c l u d e <s y s / t y p e s . h> #i n c l u d e <s y s / s o c k e t . h> i n t connect ( i n t sockfd , struct sockaddr ∗ serv_addr , i n t addrlen ) Especifica o endereço (addrPtr) ao qual o cliente se quer ligar. Retorna 0 se tiver sucesso ou -1 se falhar. André Restivo (FEUP) Sockets April 29, 2013 13 / 27 API C++ listen Exemplo int l i s t e n ( int sockfd , int backlog ) ; size: número de ligações que podem ficar pendentes. Normalmente no máximo 5. Retorna 0 se tiver sucesso ou -1 se falhar. André Restivo (FEUP) Sockets April 29, 2013 14 / 27 API C++ accept Exemplo #i n c l u d e <s y s / t y p e s . h> #i n c l u d e <s y s / s o c k e t . h> i n t a c c e p t ( i n t s o c k f d , s t r u c t s o c k a d d r ∗ addr , s o c k l e n _ t ∗ a d d r l e n Retorna o socket id e endereço do cliente que se ligou ao socket. lenPtr: máximo tamanho da estrutura do endereço. Retorna o valor real. Espera por uma ligação, e quando esta chega cria um socket para ela. André Restivo (FEUP) Sockets April 29, 2013 15 / 27 API C++ Tipos de Servidor Duas formas de usar o accept: Servidor iterativo: Apenas um socket é aberto de cada vez. Quando uma ligação termina, o socket é fechado e podemos aceitar outra ligação. Servidor multi-processo: Depois de um accept é criado um novo process/thread filho para tratar da ligação. Em alguns casos os processos filho são criados mesmo antes das ligações serem aceites. André Restivo (FEUP) Sockets April 29, 2013 16 / 27 API C++ Tipos de Servidor André Restivo (FEUP) Sockets April 29, 2013 17 / 27 API C++ send Exemplo i n t s e n d ( i n t s o c k f d , c o n s t v o i d ∗msg , i n t l e n , i n t f l a g s ) ; Envia uma mensagem. Retorna o número de bytes enviados ou -1 em caso de erro. flag normalmente = 0 Com a flag a 0 é o mesmo que: Exemplo i n t w r i t e ( i n t s o c k f d , c o n s t v o i d ∗msg , i n t l e n ) ; // f l a g s = 0 André Restivo (FEUP) Sockets April 29, 2013 18 / 27 API C++ recv Exemplo i n t r e c v ( i n t s o c k f d , v o i d ∗ buf , i n t l e n , i n t f l a g s ) ; Recebe até, no máximo, len bytes no bufferPtr. Retorna o número de bytes recebidos ou -1 no caso de falhar. flag normalmente = 0 Com a flag a 0 é o mesmo que: Exemplo i n t r e a d ( i n t s o c k f d , v o i d ∗ buf , i n t l e n ) ; André Restivo (FEUP) Sockets April 29, 2013 19 / 27 API C++ close / shutdown Exemplo close ( sockfd ); i n t shutdown ( i n t s o c k f d , i n t how ) ; how pode ser: 0 Deixa de receber dados 1 Deixa de enviar dados 2 Deixa de enviar e receber dados André Restivo (FEUP) Sockets April 29, 2013 20 / 27 Exemplo Outline 1 Introdução 2 Cliente/Servidor 3 API C++ 4 Exemplo André Restivo (FEUP) Sockets April 29, 2013 21 / 27 Exemplo Inicializar Socket Exemplo s o c k f d = s o c k e t ( AF_INET , SOCK_STREAM, 0 ) ; i f ( s o c k f d < 0) { c o u t << " E r r o r ␣ c r e a t i n g ␣ s o c k e t " << e n d l ; e x i t ( −1); } André Restivo (FEUP) Sockets April 29, 2013 22 / 27 Exemplo Criar Estrutura do Endereço Exemplo b z e r o ( ( c h a r ∗ ) &s e r v _ a d d r , s i z e o f ( s e r v _ a d d r ) ) ; s e r v _ a d d r . s i n _ f a m i l y = AF_INET ; s e r v _ a d d r . s i n _ a d d r . s _ a d d r = INADDR_ANY ; serv_addr . sin_port = htons ( port ) ; André Restivo (FEUP) Sockets April 29, 2013 23 / 27 Exemplo Fazer Bind ao Socket Exemplo i n t r e s = b i n d ( s o c k f d , ( s t r u c t s o c k a d d r ∗) &s e r v _ a d d r , s i z e o f ( s e r v _ a d d r ) ) ; i f ( r e s < 0) { c o u t << " E r r o r ␣ b i n d i n g ␣ t o ␣ s o c k e t " << e n d l ; e x i t ( −1); } André Restivo (FEUP) Sockets April 29, 2013 24 / 27 Exemplo Ficar à espera de ligações Exemplo l i s t e n ( sockfd , 5 ) ; client_addr_length = sizeof ( cli_addr ); n e w s o c k f d = a c c e p t ( s o c k f d , ( s t r u c t s o c k a d d r ∗) &c l i _ a d d r , &c l i e n t _ a d d r _ l e n g t h ) ; André Restivo (FEUP) Sockets April 29, 2013 25 / 27 Exemplo Comunicar Exemplo bzero ( buffer , 256); while ( i n t n = r e c v ( newsockfd , b u f f e r , 255 , 0) > 0) { c o u t << " R e c e i v e d ␣ message : ␣ " << b u f f e r << e n d l ; n = s e n d ( n e w s o c k f d , " I ␣ g o t ␣ y o u r ␣ message \n " , 1 9 , 0 ) ; bzero ( buffer , 256); } André Restivo (FEUP) Sockets April 29, 2013 26 / 27 Exemplo Fechar os Sockets Exemplo c l o s e ( newsockfd ) ; close ( sockfd ); André Restivo (FEUP) Sockets April 29, 2013 27 / 27