Redes de Computadores I



Documentos relacionados
TROCA DE MENSAGENS SOCKETS. Comunicando processos através de SOCKETS. SOCKETS com conexão. SOCKETS sem conexão

Sistemas de Operação Sockets

Programação com Sockets TCP e UDP - Cliente. Gustavo Leitão

sockets interprocess communication Taisy Weber

Cliente/Servidor. Programação com Sockets. Graça Bressan. Graça Bressan/LARC

Bibliotecas. Apoio à Programação Distribuída. Socket. Socket. bibliotecas bibliotecas+ferramentas linguagens de programação distribuídas

Programação de Sockets em C/C++

Sistemas de Operação (2018/2019) Ficha 6

Aula de Socket. Rafael De Tommaso do Valle

MC823 Atividade 1: Cliente/Servidor TCP Iterativo. 3 Modificando o servidor para retornar data e hora

Obter conhecimentos básicos sobre programação socket para desenvolver softwares clientes.

Comunicação entre Processos

Aula Prática. Comunicação em SOCKTS. Disciplina: INF01151

Sistemas Distribuídos (Parte 4 - Aplicação Distribuída)

06/10/2015. Modelo TCP/IP Camada de Transporte DISCIPLINA: TECNOLOGIA DE REDES DE COMPUTADORES. UDP User Datagram Protocol. UDP User Datagram Protocol

Programação de Aplicações em. Rede usando Sockets

Um Tutorial sobre Sockets Parte I

Introdução à Programação com Sockets. Fernando Jorge Silveira Filho Daniel Sadoc Menasché

Servidor TCP. Programação Sockets. (c) Volnys Bernal. Servidor TCP Resumo das Chamadas TCP. Resumo das Chamadas TCP. Resumo das Chamadas TCP

Sumário. Introdução ao TCP/IP e à Internet API Sockets para comunicação via redes Exemplos

Tutorial de Sockets - Parte I Por: Frederico Perim

INF01018 Aula Prática 1 Cliente-Servidor e Multicast

Programação com Sockets. Redes de Computadores I 2007/2008

Introdução à Programação Sockets

1 Projeto de software de clientes. 1

Comunicação entre processos. Sistema centralizado

REDES INTEGRADAS DE TELECOMUNICAÇÕES I 2012 / 2013

Servidor TCP Volnys Borges Bernal Depto de Engenharia de Sistemas Eletrônicos Escola Politécnica da USP

Comunicação entre Processos Canal de comunicação Arquitetura da comunicação Modelos de comunicação

Sockets. André Restivo. April 29, Faculdade de Engenharia da Universidade do Porto. André Restivo (FEUP) Sockets April 29, / 27

Programação Orientada a Objetos para Redes de Computadores. Modelo Cliente-Servidor. Comunicação entre Processos. O que é um Socket?

Programação Orientada a Objetos para Redes de Computadores

Modelo Cliente/Servidor e Introdução a Sockets

Resolução de Nomes e Endereços

Leandro Soares de Sousa (DSc.) Página: Aula 05 - desenvolvimento com sockets

Cliente UDP. Programação sockets. Agenda. Cliente UDP. Resumo de Chamadas UDP. Chamadas UDP. Resumo de Chamadas UDP.

Cliente UDP. Programação sockets. Agenda. Cliente UDP. Resumo de Chamadas UDP. Resumo das chamadas UDP. Resumo de Chamadas UDP.

Grupo I [6 v] Considere o processo com a seguinte tabela de páginas: Página Presente Protecção Base 0 0 RW RW R R RW -

Programação TCP/IP (sockets)

Redes de Computadores

Cliente TCP. Programação sockets. Agenda. Cliente TCP. Chamadas sockets para TCP. Chamada socket() Chamada socket()

MC823 Laboratório de Teleprocessamento e Redes

Comunicação em Sistemas Distribuídos. Conceitos: Paradigma C/S. Conceitos: Paradigma C/S. Paradigma Cliente/Servidor

Servidor UDP Volnys Borges Bernal Departamento de Sistemas Eletrônicos Escola Politécnica da USP

Relatório do Laboratório 3

Servidor TCP. Programação Sockets. (c) Volnys Bernal. Servidor TCP Resumo das Chamadas TCP. Resumo das Chamadas TCP. Resumo das Chamadas TCP

Servidor TCP. Programação Sockets. (c) Volnys Bernal. Servidor TCP Resumo das Chamadas TCP. Resumo das Chamadas TCP. Resumo das Chamadas TCP

Programação em Sockets visando verificar a diferença entre transmissão confiável (TCP) e não confiável (UDP)

API de Sockets. Modelo Cliente/Servidor (2/2) Modelo Cliente/Servidor (1/2) José Pedro Oliveira Sistemas Operativos I

Comunicação entre Processos

Engenharia Elétrica Eletrônica Slides 20: TCP/IP em Winsocks 2. API do Windows para programar utilizando o protocolo TCP/IP Prof. Jean Marcelo SIMÃO

Cliente-servidor com Sockets TCP

Servidor UDP. Programação Sockets Volnys Bernal. Servidor UDP Resumo das Chamadas UDP. Resumo de Chamadas UDP. Resumo de Chamadas UDP

UNIVERSIDADE. Sistemas Distribuídos

Resolução de Nomes Volnys Borges Bernal Deparatamento de Sistemas Eletrônicos Escola Politécnica da USP

6. Comunicação entre processos - Pipes

Leandro Soares de Sousa (DSc.) Página: Parte III

Comunicação entre Processos. 1. Pipes 2. Fifos 3. Sockets

Eng.ª Informática. Redes de Computadores. Frequência. 4 de Julho de 2006

Sistemas Distribuídos Java Sockets

Programação de Sistemas. Sockets. Programação de Sistemas Sockets : 1/66

Sistema de Entrada/Saída

Programação com sockets (em Java)

Redes de Computadores. 1 Questões de múltipla escolha. TE090 - Prof. Pedroso. 30 de novembro de Exercício 1: Considere:

TP4. Apoio ao projeto 4: tópicos avançados de sockets

29-Aug-07. Histórico. Interfaces e Periféricos Redes como interfaces. Abstração da infraestrutura de rede como interface

Introdução. Manipulação de arquivos em C. Estrutura de Dados II Prof Jairo Francisco de Souza

Introdução à Programação Sockets. Programação Sockets. (c) Volnys Bernal. Agenda. Introdução à Programação Sockets

Programação de Sistemas

Sistemas Distribuídos

Comunicação entre pai e filho

Tubos ou Pipes de Comunicação

Cliente-servidor com Sockets TCP

Trabalho 02: Cliente e Servidor em C

AInterface que um aplicativo utiliza quanto interage com um módulo implementado por outro software

Sistemas de Telecomunicações 2011/2012

socket Objetivo: aprender a construir aplicações cliente/servidor que se comunicam usando sockets

Comunicação Inter-Processos. Prof. Adriano Fiorese. Conceitos Iniciais

Preparando um esquema de endereçamento de sua rede

Sockets. Bruno Guimarães Lucas Rossini

UMA ABORDAGEM SOBRE A INTERFACE DE PROGRAMAÇÃO DE APLICAÇÕES SOCKETS E A IMPLEMENTAÇÃO DE UM SERVIDOR HTTP

Sistemas Operacionais:

Redes de Computadores (PPGI/UFRJ)

LEIC/LERC 2012/13 2º Teste de Sistemas Operativos 15/Janeiro/2013

Volnys Borges Bernal. Agenda. Resolução de Nomes. Introdução à resolução de nomes. Introdução à resolução de nomes


Agentes Inteligentes segundo o Chimera

ICORLI. INSTALAÇÃO, CONFIGURAÇÃO e OPERAÇÃO EM REDES LOCAIS e INTERNET

Sistemas Operacionais II

Protocolo de resolução de endereços: ARP

Cliente UDP. Programação sockets. Agenda. Cliente UDP. Resumo de Chamadas UDP. Chamadas UDP. Resumo de Chamadas UDP.

Programação paralela em UNIX. Aleardo Manacero Jr.

Redes de Computadores (RCOMP 2014/2015)

Sockets - Conceitos Básicos. COMUNICAÇÃO ENTRE PROCESSOS Sockets. Conceitos Básicos. Tipos de Sockets

Protocolos de Aplicação

Sistemas Operacionais - Básico e Avançado - Prof. Celso Maciel da Costa Mestrado em Informática - PUCRS

Introdução. Protocolos de Aplicação. Introdução à pilha de comunicações TCP/IP. Interface de sockets. Protocolos de aplicação. Exemplos de trabalhos

Transcrição:

Departamento de Engenharia Electrotécnica e de Computadores Secção de Telecomunicações Redes de Computadores I Introdução à Interface "Socket" do UNIX Licenciatura de Engenharia Informática e de Computadores Prof. Vitor Vargas Eng. Paulo Pereira Eng. Luís Bernardo

SOCKETS Domínio INTERNET: Camadas Conceptuais Socket Transporte Organização de Software Socket Protocolo 1 Protocolo 2 Protocolo 3 Internet Interface de Rede Módulo IP Interface 1 Interface 2 Interface 3 int socket (int domain, int type, int protocol) ; Cria um porto para comunicação assíncrona, bidireccional e retorna um descritor (idêntico aos utilizados nos ficheiros e pipes). domain - domínio onde o socket é criado, que define os protocolos e o espaço de nomes. type PF_UNIX - Domínio Unix, local a uma máquina PF_INET - Domínio Inet, redes Internet SOCK_STREAM - orientado à ligação, comunicação fiável e sequencial. SOCK_DGRAM - sem ligação, mensagens limitadas no comprimento, comunicação sem garantia de sequencialidade, fiabilidade ou não existência de duplicações. protocol - depende do domínio. Normalmente é colocado a zero, que indica o protocolo por omissão no domínio respectivo (TCP, UDP). int bind (int s, struct sockaddr *name, int namelen) ; Associa um nome a um socket já criado. s - identificador do socket. name - o nome depende do domínio onde o socket foi criado. No domínio UNIX corresponde a um "pathname". No domínio Internet é do tipo struct sockaddr_in, que é composto pelo endereço da máquina, protocolo e número de porto. namelen - inteiro igual a sizeof(*name) int close (int s) ; 1

Connectionless (SOCK_DGRAM) Servidor socket ( ) bind ( ) recvfrom ( ) Cliente socket ( ) bloqueia até receber dados de um cliente processa pedido sendto ( ) dados(pedido) dados(resposta) sendto ( ) recvfrom ( ) int sendto (int s, char *msg, int len, int flags, struct sockaddr *to, int tolen) ; Envia uma mensagem através do socket s para o socket especificado em to independentemente de existir ou não ligação estabelecida entre os dois sockets. msg - mensagem a enviar. len - dimensão da mensagem a enviar flags : MSG_OOB - Out of band to - endereço do socket para onde vai ser enviada a mensagem. tolen - inteiro igual a sizeof(*to) int recvfrom (int s, char *buf, int len, int flags, struct sockaddr *from, int * fromlen) ; ou int recv (int s, char *buf, int len, int flags) ; ou int read (int s, char *buf, int len) ; Recebe uma mensagem através do socket s de um socket remoto independentemente de existir ou não ligação estabelecida entre os dois. Devolve o tamanho da mensagem lida. buf - buffer para a mensagem a receber. len - dimensão do buffer. flags : MSG_OOB - Out of band. MSG_PEEK- Ler sem consumir. from - endereço do socket que enviou a mensagem. fromlen - ponteiro para inteiro inicializado a sizeof(*from). 2

Connection-oriented (SOCK_STREAM) Servidor socket ( ) bind ( ) listen ( ) accept ( ) bloqueia até ter ligação de um cliente estabelecimento de ligação Cliente socket ( ) connect ( ) read ( ) processa pedido write ( ) dados(pedido) dados(resposta) write ( ) read ( ) int connect (int s, struct sockaddr *name, int namelen) ; Estabelece uma ligação entre o socket s e o outro socket indicado em name. int listen (int s, int backlog) ; Indica que o socket s pode receber ligações. backlog - comprimento da fila de espera de novos pedidos de ligação. int accept (int s, struct sockaddr *addr, int * addrlen) ; Bloqueia o processo até um processo remoto estabelecer uma ligação. Retorna o identificador de um novo socket para transferência de dados. int send (int s, char *msg, int len, int flags) ; ou int write(int s, char *msg, int len) ; Envia uma mensagem através do socket s para o socket remoto associado. Retorna o número de bytes efectivamente enviados, ou -1 em caso de erro. No caso de a ligação ser cortada, o processo pode receber um signal SIGPIPE. int recv (int s, char *buf, int len, int flags) ; ou int read (int s, char *buf, int len) ; Recebe uma mensagem do socket remoto através do socket s. Retorna o número de bytes lidos, ou 0 se a ligação foi cortada, ou -1 se a operação foi interrompida. int shutdown (int s, int how) ; how: 0 - no more reading, 1 - no more writing, 2 - no more reading or writing. 3

Multiplexagem das Entradas/Saídas ( select ) #include <sys/types.h> #include <sys/time.h> int select ( int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) ; Bloqueia o processo até que uma das operações de E/S pendentes se realize. Entradas: Saídas : máscaras readfds, writefds, exceptfds - padrão de bits indicando os descritores de E/S sobre os quais se pretende efectuar operações de Leitura, Escrita ou processar Excepções. width - número do maior descritor a considerar na máscara + 1. Este parâmetro pode ser preenchido com o valor retornado pela função getdtablesize() que retorna o número máximo de descritores que pode estar associado a um processo, ou com a macro FD_SETSIZE. timeout - tempo de espera (0 = bloqueio) máscaras readfds, writefds, exceptfds - padrão de bits indicando os descritores "ready". Retorna - número de descritores "ready", 0 se expirou o timeout, -1 se foi interrompido ou se houve um erro. Para modificar os bits das máscaras são utilizadas as funções (macros): FD_ZERO (fd_set *fdset) Coloca todos os bits da máscara a 0. FD_SET (int fd, fd_set *fdset) Liga o bit correspondente ao descritor de ficheiro fd. FD_CLR (int fd, fd_set *fdset) Limpa o bit correspondente ao descritor de ficheiro fd. FD_ISSET (int fd, fd_set *fdset) Testa se o bit correspondente ao descritor de ficheiro fd está activo. Em versões antigas do Unix foi utilizado o tipo int em vez de fd_set, mas nesse caso, o máximo valor de width suportado é 32. É possível obter o descritor do teclado com: fileno(stdin) 4

Exemplo de utilização ( leitura bloqueante de mensagens de 2 descritores ) : #define NO_DESC 0 #define BLOCK 0 fd_set rmask; /* máscara de leitura */ int sd1, sd2, /* Descritores de sockets */ n; FD_ZERO(&rmask); FD_SET(sd1, &rmask); FD_SET(sd2, &rmask); n= select (getdtablesize(), &rmask, NO_DESC, NO_DESC, BLOCK); if (n <= 0) { fprintf(stderr, "Interruption of select\n");... else { if (FD_ISSET(sd1, &rmask)) { /* Há dados disponíveis para leitura no socket sd1 */... if (FD_ISSET(sd2, &rmask)) { /* Há dados disponíveis para leitura no socket sd2 */... Configurar um socket para escrita não bloqueante Para que uma chamada sistema de escrita num socket s não seja bloqueante devese ligar a flag NDELAY: #include <sys/fcntl.h> int flags; if ((flags= fcntl(s, F_GETFL)) < 0) perror("fcntl error getting socket flags"); flags = O_NDELAY; if (fcntl(s, F_SETFL, flags) < 0) perror("fcntl error setting NO DELAY on socket"); Outro método de obter o mesmo resultado: #include <sys/filio.h> int nonblock=1; if (ioctl(s, FIONBIO, &nonblock) < 0) perror("ioctl error setting NO DELAY on socket"); 5

As funções apresentadas anteriormente retornam o valor -1 em caso de falha. A variável errno é afectada com o código da ocorrência. perror escreve a mensagem de erro do sistema operativo associada a esse código de erro. Em seguida apresenta-se a definição de alguns dos tipos referidos anteriormente: <sys/time.h>: struct timeval { long tv_sec; /* seconds */ long tv_usec; /* and microseconds */ ; <sys/socket.h>: struct sockaddr { u_short sa_family; /* Address family : AF_xxx */ char sa_data[14]; /* up to 14 bytes of protocol specific address */ ; <netinet/in.h>: struct in_addr { u_long s_addr; /* 32-bit netid/hostid network byte ordered */ ; struct sockaddr_in { short sin_family; /* AF_INET */ u_short sin_port; /* 16-bit port number network byte ordered */ struct in_addr sin_addr; /* 32-bit netid/hostid network byte ordered */ char sin_zero[8]; /* unused */ ; <netdb.h>: 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, null terminated */ ; #define h_addr h_addr_list[0] /* first address, network byte order */ <sys/types.h>: typedef long fd_mask; typedef struct fd_set { fd_mask fds_bits[... ]; fd_set; 6

Dados fora de banda (OOB) em sockets orientados à conexão Os sockets orientados à conexão suportam o envio de dados fora de banda constituídos por um byte de informação. Uma possível utilização é o envio de CONTROL-C. O envio de dados fora de banda é feito utilizando a função send() com a flag MSG_OOB. A recepção dos dados pode ser síncrona, mantendo-se a ordem em relação aos dados normais com que foram enviados. Nesse caso, pode-se utilizar qualquer das primitivas descritas anteriormente para ler dados de sockets. A função ioctl permite descobrir se os próximos dados lidos do socket s são "fora de banda" ou normais: int yes; ioctl (s, SIOCATMARK, &yes); if (yes) { /* dados fora de banda */ else { /* dados normais */ Outra hipótese será fazer leitura assíncrona, associando o signal SIGURG à recepção de dados fora de banda. Essa associação é feita utilizando a função ioctl sobre o socket s, fornecendo como parâmetro o pid do processo vezes -1, como está representado: #ifdef sun #include <sys/sockio.h> #else #include <sys/ioctl.h> #endif int pid= -getpid(); if (ioctl(s, SIOCSPGRP, (char *)&pid) < 0) { perror ("ioctl: SIOCSPGRP,"); Neste caso, os dados fora de banda são lidos na rotina de tratamento do signal, utilizando a função recv() ou recvfrom() com a flag MSG_OOB. 7

Funções auxiliares Existem definidas um conjunto de funções de biblioteca. struct hostent *gethostbyname(char *hostname); Devolve o identificador de host/rede associado ao hostname. unsigned long inet_addr(char *cp); Converte uma string cp na notação standard da Internet d.d.d.d no endereço IP em formato rede, devolvendo -1 em caso de erro. char *inet_ntoa(struct in_addr in); Converte o endereço IP in, no formato rede para uma string com o endereço d.d.d.d associado. No quadro seguinte apresenta-se um excerto de um programa com o preenchimento de uma estrutura sockaddr_in com um endereço dado pelo número de porto e nome do host (máquina). #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> char *host_name= "mega.ist.utl.pt"; struct sockaddr_in addr; struct hostent *hp;... hp= gethostbyname(host_name); if (hp == NULL) { fprintf (stderr, "%s : unknown host\n", host_name);... bzero((char *)&addr, sizeof addr); bcopy (hp->h_addr, (char *) &addr.sin_addr, hp->h_length); addr.sin_family= AF_INET; addr.sin_port= htons(port_number); printf("built address %s:%d\n", inet_ntoa(addr.sin_addr), (int)ntohs(addr.sin_port)); 8

Quando se está a preencher a estrutura para uma chamada à função bind, pode-se inicializar o campo sin_addr.s_addr com INADDR_ANY, que fica automaticamente associado a todos os endereços IP do host local. Se o porto for inicializado a 0, então é atribuído um valor durante a chamada a bind. int getsockname ( int s, struct sockaddr *addr, int *addrlen ); Utilizada para obter a estrutura com o endereço associado ao socket s. Em seguida apresenta-se um excerto de um programa, onde se obtém o número de porto associado a um socket s. struct sockaddr_in addr; int len= sizeof(addr);... if (getsockname(s, &addr, &len)) { fprintf(stderr, "Error getting socket name\n"); if (addr.sin_family!= AF_INET) { fprintf(stderr, "Nao e' socket INET\n");... printf("socket has port #%d\n", ntohs(addr.sin_port)); Outras funções C Run-time Routines : Call bcmp (s1, s2, n) bcopy (s1, s2, n) bzero (base, n) htonl (val) htons (val) ntohl (val) ntohs (val) Synopsis Compare byte-strings; 0 if same, not 0 otherwise Copy n bytes from s1 to s2 Zero-fill n bytes starting at base 32-bit quantity (long) from host into network byte order 16-bit quantity (short) from host into network byte order 32-bit quantity (long) from network into host byte order 16-bit quantity (short) from network into host byte order 9

Para permitir a portabilidade do código para máquinas que utilizem uma ordem dos bytes diferentes da ordem utilizada na rede, devem ser utilizadas as rotinas?to?? (em <netinet/in.h>) para manipular as componentes dos endereços. Estas funções também podem ser utilizadas para possibilitar a transmissão de shorts e ints entre máquinas que usam uma ordem diferente dos bytes. Note-se que a função memcpy tem os argumentos pela ordem inversa de bcopy, e o seu correcto funcionamento não é garantido quando as zonas de memória se sobrepõem. A função bcopy trata correctamente de sobreposições. Em alguns sistemas operativos tem o nome memmove. A função bzero pode ser substituída por memset com os parâmetros adequados. Por razões de eficiência, deve-se evitar cópias e limpezas de memória desnecessárias. 10

Exemplo de envio de dados datagram no domínio Internet. #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define DATA "The sea in calm tonight, the tide is full..." /* * Here I send a datagram to a receiver whose name I get * from the command line arguments. */ main (int argc, char *argv[]) { int sock; struct sockaddr_in name; struct hostent *hp; /* Create socket on which to send. */ sock = socket(pf_inet, SOCK_DGRAM, 0); if (sock < 0) { perror("opening datagram socket"); /* * Construct name, with no wildcards, of the socket to send * to. Gethostbyname() returns a structure including the * network address of the specified host. The port number * is taken from the command line. */ hp = gethostbyname(argv[1]); if (hp == 0) { fprintf(stderr, "%s: unknown host\n", argv[1]); exit(2); bcopy(hp->h_addr, &name.sin_addr, hp->h_length); name.sin_family = AF_INET; name.sin_port = htons(atoi(argv[2])); /* Send message. */ if (sendto(sock, DATA, strlen(data)+1, 0, &name, sizeof(name)) < 0) perror("sending datagram message"); close(sock); 11

Exemplo de recepção de dados datagram no domínio Internet. #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <unistd.h> /* * This program creates a datagram socket, binds a name * to it, then reads from the socket. */ #define BUFSIZE 1024 main () { int struct sockaddr_in int char sock, length; name, from; fromlen= sizeof(from); buf[bufsize]; /* Create socket on which to read. */ sock = socket(pf_inet, SOCK_DGRAM, 0); if (sock < 0) { perror("opening datagram socket"); /* Create name with wildcards. */ name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = 0; if (bind(sock, &name, sizeof(name))) { perror("binding datagram socket"); /* Find assigned port value and print it out. */ length = sizeof(name); if (getsockname(sock, &name, &length)) { perror("getting socket name"); printf("socket has port #%d\n", ntohs(name.sin_port)); /* Read from the socket */ if (recvfrom(sock, buf, BUFSIZE, 0, &from, &fromlen) < 0) perror("receiving datagram packet"); printf("-->%s\n", buf); close(sock); 12

Exemplo de envio de dados stream no domínio Internet. #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define DATA "Half a league, half a league..." /* * This program creates a socket and initiates a connection * with the socket given in the command line. One message * is sent over the connection and then the socket is * closed, ending the connection. */ main (int argc, char *argv[]) { int sock; struct sockaddr_in server; struct hostent *hp; /* Create socket */ sock = socket(pf_inet, SOCK_STREAM, 0); if (sock < 0) { perror("opening stream socket"); /* Connect socket using name specified by command line. */ hp = gethostbyname(argv[1]); if (hp == 0) { fprintf(stderr, "%s: unknown host\n", argv[1]); bcopy(hp->h_addr, &server.sin_addr, hp->h_length); server.sin_family = AF_INET; server.sin_port = htons(atoi(argv[2])); if (connect(sock, &server, sizeof(server)) < 0) { perror("connecting stream socket"); if (write(sock, DATA, strlen(data)+1) < 0) perror("writing on stream socket"); close(sock); 13

Exemplo de recepção de dados stream no domínio Internet. #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <unistd.h> #define BUFSIZE 1024 main () { int sock, msgsock, length, n; struct sockaddr_in server; char buf[bufsize+1]; /* Create socket on which to read. */ sock = socket(pf_inet, SOCK_STREAM, 0); if (sock < 0) { perror("opening stream socket"); /* Create name with wildcards. */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = 0; if (bind(sock, &server, sizeof(server))) { perror("binding stream socket"); /* Find assigned port value and print it out. */ length = sizeof(server); if (getsockname(sock, &server, &length)) { perror("getting socket name"); printf("socket has port #%d\n", ntohs(server.sin_port)); /* Start accepting connections */ listen (sock, 5); while (1) { msgsock = accept(sock, 0, 0); if (msgsock == -1) perror("accept"); else { if ((n=read(msgsock, buf, BUFSIZE)) < 0) perror("receiving stream data"); else if (n==0) fprintf(stderr, "EOF\n"); else { buf[n]='\0'; printf("-->%s\n", buf); close(msgsock); 14

Exemplo de utilização da instrução select()com sockets orientados à conexão no domínio Internet. /* Processo Servidor */ #include <sys/types.h> #include <sys/socket.h> #define BUFSIZE 1024 #define BLOCK 0 #define NO_DESC 0 int which (fd_set *mask) {... procurar primeiro bit ligado... main () { int fd_set char struct sockaddr_in sd, ns, n, fromlen, active; rmask, Rmask; buf[bufsize]; NameSocket, OtherSocket; sd = socket (PF_INET, SOCK_STREAM, 0);... Preenchimento do endereço em NameSocket... bind (sd, &NameSocket, sizeof(struct sockaddr_in)); listen (sd, 1); FD_ZERO(&rmask); FD_SET(sd, &rmask); fromlen= sizeof(struct sockaddr_in); for ( ; ; ) { memcpy(&rmask, &rmask, sizeof(rmask)); select (FD_SETSIZE, &Rmask, NO_DESC, NO_DESC, BLOCK); active= which (&Rmask); if (active == sd) { /* Recepção no socket de Ligações */ ns= accept (sd, &OtherSocket, &fromlen); FD_SET (ns, &rmask); else { /* Recepção num socket ordinário */ n= read (active, buf, BUFSIZE); if (n>0) printf("o serviço recebeu %.*s\n", n, buf); else { /* == 0: fim de ligação; == -1: erro */... Tratamento do fim de ligação, ou erro... FD_CLR(active, &rmask); close(active); 15