100 likes | 216 Views
Formato das estruturas de dados Estrutura sockaddr struct sockaddr { short int sa_family; /*Address family */ unsigned char sa_data[14]; /* 14 bytes of protocol address */ }; Estrutura sockaddr_in struct sockaddr_in {
E N D
Formato das estruturas de dados Estrutura sockaddr struct sockaddr { short int sa_family; /*Address family */ unsigned char sa_data[14]; /* 14 bytes of protocol address */ }; Estrutura sockaddr_in struct sockaddr_in { short int sin_family; /*Address family */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ /* Pad to size of `struct sockaddr'. */ unsigned char pad[sizeof(struct sockaddr) - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)]; }; Estrutura in_addr struct in_addr { unsigned long s_addr; }; Estrutura hostent struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses */ } /* for backward compatibility */ #define h_addr h_addr_list[0] Isidro Vila Verde (jvv@fe.up.pt)
Primitivas Socket Cria um “ponto terminal” para comunicação e devolve um descritor do socket. Sintaxe: int socket(int domain, int type, int protocol); Domain: AF_INET /*Internet protocol Family*/ AF_UNIX /*Unix internal comunication Family*/ AF_ATMPVC /*ATM PVC (linux)*/ AF_ATMSVC /*ATM PVC (linux)*/ Type: SOCK_STREAM SOCK_DGRAM SOCK_RAW Protocol Especifíca o código do protocolo (TCP,UDP,etc) a ser usado. Se indicar 0 (zero) a interface escolhe um. Bind Associa o socket com um endereço local. Sintaxe: int bind(int s, struct sockaddr *my_addr, int addrlen); s é o descritor do socket. my_addr deve apontar para uma estrutura onde esteja defenido o endereço local, ao qual se pretende associar o socket s. Na INTERNET o endereço local é composto pelo endereço IP local (normalmente INADDR_ANY, que significa qualquer um) e pelo porto TCP (ou UDP) pretendido. Isidro Vila Verde (jvv@fe.up.pt)
Primitivas Listen Define o tamanho da fila de espera para pedidos de conexão vindos da rede. Sintaxe: int listen(int s, int backlog) s é o descritor do socket. backlog define o número de pedidos que podem estar pendentes na fila de espera. Accept Espera a chegada de um pedido de ligação e retorna um novo socket associado a essa mesma ligação Sintaxe:int accept(int s, struct sockaddr *addr, int *addrlen) s é o descritor do socket. addr deve apontar para uma estrutura do tipo sockaddr. Após o retorno do accept, esta estrutura identifica o endereço do host remoto. Na INTERNET indica quer o endereço IP quer o porto TCP. addrlen deve apontar para um inteiro cujo valor é sizeof(sockaddr). Nota: s deve ser visto como se fosse um socket de controlo. A transferência de dados (send e recv) é, obrigatoriamente, feita no socket devolvido pela primitiva. Isidro Vila Verde (jvv@fe.up.pt)
Primitivas Connect Establece uma ligação para um endereço remoto Sintaxe: int connect(int s, struct sockaddr *serv_addr, int addrlen ); s é o descritor do socket. serv_addr aponta para uma estrutura contendo o endereço do serviço remoto. Na INTERNET este endereço deve conter quer o endereço IP do host quer o porto TCP usado. addrlen indica o tamanho da estrutura apontada por serv_addr. Recv Recebe, num buffer, dados vindos da rede (é um read) . Sintaxe: int recv(int s, void *buf, int len, unsigned int flags); s é o descritor do socket. buf deve apontar para um buffer com pelo menos len bytes de comprimento, onde serão colocados, pela primitiva, os dados recebidos. flags assume normalmente o valor 0 (zero). Retorna: o número de bytes recebidos; ou zero quando a ligação foi fechada pelo host remoto; ou -1 em caso de erro; Isidro Vila Verde (jvv@fe.up.pt)
Primitivas Send Envia o conteúdo de um buffer para a rede (é um write) . Sintaxe: int send(int s, void *buf, int len, unsigned int flags); s é o descritor do socket. buf deve apontar para um buffer contendo os dados a serem enviados. len indica o número de bytes que se pretende transmitir. flags assume normalmente o valor 0 (zero). Retorna: o número de bytes enviados; ou zero quando a ligação foi fechada pelo host remoto; ou -1 em caso de erro; Htons Converte para formato de rede um número de 16bits. Sintaxe: unsigned short int htons(unsigned short int n) É normalmente usado para converter o número do porto. Inet_addr Converte para formato da rede uma string na forma x.x.x.x, onde x é um valor entre 0 e 255. Sintaxe: unsigned long int inet_addr(const char *cp); Exemplo: inet_addr(“193.136.28.15”); Isidro Vila Verde (jvv@fe.up.pt)
Primitivas Gethostbyname Dado o nome de uma máquina devolve um ponteiro para uma estrutura do tipo hostent. O número IP pode (então) ser obtido a partir do campo hostent::h_addr Sintaxe: struct hostent *gethostbyname(const char *name); Exemplo: struct hostent* p = gethostbyname(“alf.fe.up.pt”); sockaddr_in addr; bcopy((char*)p->h_addr,(char*)&addr.sin_addr.s_addr, p->h_length); Isidro Vila Verde (jvv@fe.up.pt)
Sequência de Operações (STREAM socket) Socket() Bind() Listen() Socket() Connect() Send/Recv() Send/Recv() Servidor TCP Cliente TCP Accept() Isidro Vila Verde (jvv@fe.up.pt)
Primitivas Recvfrom Idêntica ao Recv, mas pode ser usada em sockets no estado disconnected. Sintaxe: int recvfrom(int s, void *buf, int len, unsigned int flags struct sockaddr *from, int *fromlen) Ao retornar a estrutura apontada por from contém o endereço (port+ipaddress) da aplicação peer. Sendto Idêntica ao Send, mas pode ser usada em sockets no estado disconnected. Sintaxe: int sendto(int s, const void *msg, int len unsigned int flags, const struct sockaddr *to, int tolen); A estrutura apontada por to deve ter o endereço (port+ipaddres) da aplicação peer remota. Isidro Vila Verde (jvv@fe.up.pt)
Sequência de Operações (DGRAM socket) Socket() Bind() Socket() Bind() Sendto/Recvfrom () Sendto/Recvfrom () Servidor UDP Cliente UDP Isidro Vila Verde (jvv@fe.up.pt)
Notas sobre Sockets A primitiva Connect também pode ser invocada para um socket UDP, embora tal operação se limite a associar um socket a um endereço (port+ipaddress) remoto. Acaba por ter uma função “semelhante” à primitiva Bind, mas no que diz respeito ao peer remoto. Em TCP (no estado de transferência de dados) a cada socket está SEMPRE associado um endereço remoto. Em UDP um só socket pode servir para comunicar simultâneamente com vários peers. Por vezes (raramente) quando uma máquina possui mais do que um endereço de rede (ipaddress), as aplicações client TCP podem necessitar de definir o número IP que deve ser usado . Neste caso usa-se a primitiva Bind antes da primitiva Connect, com o campo da sin_addr.s_addr, do segundo argumento da primitiva, igual ao endereço pretendido e o campo sin_port igual zero; Isidro Vila Verde (jvv@fe.up.pt)