A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Comunicação entre processos usando Sockets Disciplina: Linguagem de Programação IV.

Apresentações semelhantes


Apresentação em tema: "Comunicação entre processos usando Sockets Disciplina: Linguagem de Programação IV."— Transcrição da apresentação:

1 Comunicação entre processos usando Sockets Disciplina: Linguagem de Programação IV

2 Revisão da aula anterior Revisão do programa fork. Revisão do programa fork. Quais são os problemas em relação aos processos pesados ? Quais são os problemas em relação aos processos pesados ?

3 Comunicação entre processos send / receive (troca de mensagens) send / receive (troca de mensagens) RPC (Remote Procedure Call) RPC (Remote Procedure Call) C. 1984, ex.: rpcinfo/portmapper. C. 1984, ex.: rpcinfo/portmapper. Objetos distribuídos. Maior nível de abstração. Objetos distribuídos. Maior nível de abstração.

4 API: Application Programming interface API: Application Programming interface API: Modelo de Programação API: Modelo de Programação disponível em muitos sistemas operacionais disponível em muitos sistemas operacionais ex: Windows NT, Unix, etc. ex: Windows NT, Unix, etc. Facilita a Programação Facilita a Programação Torna as aplicações mais flexíveis Torna as aplicações mais flexíveis

5 Revisão Sockets O que é um Socket? O que é um Socket? Socket é uma ponta de uma comunicação ponto-a-ponto entre dois programas rodando em uma rede. Socket é uma ponta de uma comunicação ponto-a-ponto entre dois programas rodando em uma rede.

6 A API SOCKET Introduzido em 1981 no UNIX BSD(Berkeley Software Distribution) 4.1 Introduzido em 1981 no UNIX BSD(Berkeley Software Distribution) 4.1

7 A API SOCKET

8 A API SOCKET - cont. Cada aplicação conhece apenas o seu próprio Socket; Cada aplicação conhece apenas o seu próprio Socket; Os sockets são explicitamente criados, usados e liberados pela própria aplicação; Os sockets são explicitamente criados, usados e liberados pela própria aplicação; Baseado no paradigma cliente/servidor; Baseado no paradigma cliente/servidor; dois tipos de serviço de transporte via API socket: dois tipos de serviço de transporte via API socket: datagramas não confiáveis datagramas não confiáveis confiáveis, orientado a conexão confiáveis, orientado a conexão

9 Sockets: visão conceitual cada socket possui o seu próprio buffer para envio e recepção de dado, número de porta, parâmetro; cada socket possui o seu próprio buffer para envio e recepção de dado, número de porta, parâmetro; As operações com o socket são construídas como chamada a funções do sistema operacional. As operações com o socket são construídas como chamada a funções do sistema operacional.

10 Endereçamento na Internet Cada máquina na Internet possui um ou mais endereços IP 32-bit únicos e globais; Cada máquina na Internet possui um ou mais endereços IP 32-bit únicos e globais; A máquina pode ter 1 ou mais endereços A máquina pode ter 1 ou mais endereços cada endereço está associado a cada placa de rede cada endereço está associado a cada placa de rede Notação de ponto decimal: Notação de ponto decimal: 4 inteiros decimais, cada grupo representando um byte de endereço IP. 4 inteiros decimais, cada grupo representando um byte de endereço IP.

11 Endereçamento na Internet A função converte da notação ponto decimal para o endereço de 32-bit; A função inet_addr() converte da notação ponto decimal para o endereço de 32-bit; A função converte o nome textual para o ponto decimal. A função gethostbyname() converte o nome textual para o ponto decimal.

12 DNS: Sistema de nomes de Domínio na Internet uma base de dados distribuída usada por aplicações TCP/IP para mapear de/para nomes de máquina para/de endereços IP. uma base de dados distribuída usada por aplicações TCP/IP para mapear de/para nomes de máquina para/de endereços IP. servidor de nomes: servidor de nomes: as funções de usuário gethostbyname() e gethostbyaddress() contactam o servidor de nome local através da porta 53 as funções de usuário gethostbyname() e gethostbyaddress() contactam o servidor de nome local através da porta 53 o servidor de nomes retorna um endereço IP do nome da máquina solicitada o servidor de nomes retorna um endereço IP do nome da máquina solicitada

13 Criando um socket Mesmo ponto comum (socket) usado para enviar/receber dados Mesmo ponto comum (socket) usado para enviar/receber dados não existe, a priori, associação do socket com a rede não existe, a priori, associação do socket com a rede deve especificar a família de protocolo, bem como o nível do serviço a ser usado com o socket: deve especificar a família de protocolo, bem como o nível do serviço a ser usado com o socket: Tipo de serviço: Datagrama (SOCK_DGRAM) = UDP Confiável (SOCK_STREAM) = TCP

14 Criando um socket - cont. int socket (int family, int service, int protocol) family um nome simbólico para a família de protocolos family um nome simbólico para a família de protocolos service um nome simbólico para o tipo de serviço service um nome simbólico para o tipo de serviço Protocol para uso futuro. Esse valor será 0. Protocol para uso futuro. Esse valor será 0. Obs.: O código de retorno da função socket() é um descritor, usado em todas as chamadas ao socket criado. Exemplo: #include #include int sockfd; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { /* handle error */ }

15 Atribuindo um endereço de rede ao socket: bind() Cada socket deve ser associado a uma porta local que deve ser única. Cada socket deve ser associado a uma porta local que deve ser única. A porta é uma abstração do protocolo TCP/IP para distinguir entre múltiplos destinos dentro de uma determinada máquina A porta é uma abstração do protocolo TCP/IP para distinguir entre múltiplos destinos dentro de uma determinada máquina Precisa especificar o endereço de rede Precisa especificar o endereço de rede O S.O. sabe que as messagens recebidas naquele endereço e porta devem ser entregues para o socket. O S.O. sabe que as messagens recebidas naquele endereço e porta devem ser entregues para o socket. Endereço de portas. Ver arquivos /etc/services. Endereço de portas. Ver arquivos /etc/services.

16 Endereçamento de Socket: estruturas de endereço pré-definidas Especificando endereços de socket: algumas estruturas de dados usadas na implementação: struct sockaddr_in { short sin_family; /* default AF_INET */ short sin_family; /* default AF_INET */ u_short sin_port; /* número de 16 bit */ u_short sin_port; /* número de 16 bit */ struct in_addr sin_addr; /* endereço de 32 bit da máquina */ char sin_zero[8]; /* n ã o usado */ struct in_addr sin_addr; /* endereço de 32 bit da máquina */ char sin_zero[8]; /* n ã o usado */}; struct in_addr { u_long s_addr; /* end. 32 bit da máquina */ u_long s_addr; /* end. 32 bit da máquina */};

17 A chamada ao bind() int bind ( int sockfd, struct sockaddr *myaddr, int addresslen) sockfd: é o número do socket obtido anteriormente. sockfd: é o número do socket obtido anteriormente. *myaddr: especifica o end. local associado ao socket(inclusive a porta). *myaddr: especifica o end. local associado ao socket(inclusive a porta). addresslen: é o tamanho da estrutura de endere o addresslen: é o tamanho da estrutura de endere o Obs.: se a função retornar um erro então o número da porta já está em uso ou fora do limite.

18 A chamada ao bind() - cont. #include #include int sockfd; struct sockaddr_in myaddr; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { /* Manipulador de erro */ } { /* Manipulador de erro */ } myaddr.sin_family = AF_INET; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(5100); myaddr.sin_port = htons(5100); myaddr.sin_addr.s_addr = htonl(INADDR_ANY); myaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* INADDR_ANY = SO determina o hostid */ /* INADDR_ANY = SO determina o hostid */ if ( bind(sockfd, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) { if ( bind(sockfd, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) { /* Manipulador de erro*/ /* Manipulador de erro*/}

19 Serviço Orientado a Conexão

20 SERVIDOR Atribui um endere o ao descritorbind() ao descritor:bind() CLIENTE cria o descritor: socket() Atribui ao descritor um endere o (opcional) :bind() Avisa que está aceitando conexões: listen() bloquea/espera novas conexões.: accept()(novos sockets criados na volta) espera pelo pkt:recv() envia resposta:send() Conectar o servidor via socket: connect() Libera o descritor: close() envia msg: send() espera a resp:recv() Cria o descritor: socket() para receber pedidos Libera o descritor: close() Determina o end. servidor Troca de msg Requisita resposta

21 Serviço Orientado a Conexão aperto de mão cliente/servidor: aperto de mão cliente/servidor: cliente deve se conectar ao servidor antes de enviar ou receber dados cliente deve se conectar ao servidor antes de enviar ou receber dados cliente não passará do connect() até o servidor aceitá-lo cliente não passará do connect() até o servidor aceitá-lo servidor deve aceitar o cliente antes de enviar ou receber dados servidor deve aceitar o cliente antes de enviar ou receber dados servidor não passará do accept() até o cliente usar connect() servidor não passará do accept() até o cliente usar connect() serviço orientado a conexão: serviço confiável oferecido pela camada de transporte. serviço orientado a conexão: serviço confiável oferecido pela camada de transporte.

22 conexão cliente-para-servidor : connect() cliente usa connect() para requisitar conexão junto ao servidor cliente usa connect() para requisitar conexão junto ao servidor protocolo da camada de transporte (ex: TCP) inicia procedimento para conexão através do aperto de mão cliente/servidor protocolo da camada de transporte (ex: TCP) inicia procedimento para conexão através do aperto de mão cliente/servidor connect() retorna quando o servidor aceita a conexão ou time-out (não há resposta) connect() retorna quando o servidor aceita a conexão ou time-out (não há resposta) usado com protocolos confiáveis, mas também com datagramas usado com protocolos confiáveis, mas também com datagramas

23 Conexão cliente-para-servidor : connect() - cont. int connect ( int sockfd, struct sockaddr *toaddrptr, int addresslen) sockfd: número do socket atribuído anteriormente. Os processos o usam para enviar conexões aceitas. sockfd: número do socket atribuído anteriormente. Os processos o usam para enviar conexões aceitas. *toaddrptr: especifica o end. Remoto (inclusive a porta). *toaddrptr: especifica o end. Remoto (inclusive a porta). Addresslen : é o tamanho da estrutura de endereço. Addresslen : é o tamanho da estrutura de endereço.

24 A chamada listen() Usado por servidores orientados a conexão. Usado por servidores orientados a conexão. avisa a rede/S.O. que o servidor aceitará requisições para conexão. avisa a rede/S.O. que o servidor aceitará requisições para conexão. Não bloqueia e não espera por requisições! Não bloqueia e não espera por requisições! int listen ( int sockfd, int maxwaiting) int listen ( int sockfd, int maxwaiting) sockfd: número do socket atribuído anteriormente. sockfd: número do socket atribuído anteriormente. maxwaiting: número máximo de conexões que podem ser enfileiradas, enquanto aguardam o servidor executar um accept(). O valor típico é 5. maxwaiting: número máximo de conexões que podem ser enfileiradas, enquanto aguardam o servidor executar um accept(). O valor típico é 5.

25 Conexão servidor-para-cliente : accept() Executado pelo servidor após listen(). Executado pelo servidor após listen(). servidor irá aceitar as novas conexões via socket novo, isto é, retornará um novo número de socket para usar na comunicação de volta ao cliente. servidor irá aceitar as novas conexões via socket novo, isto é, retornará um novo número de socket para usar na comunicação de volta ao cliente.

26 Accept() -cont. int accept ( int sockfd, struct sockaddr *fromaddrptr, int *addresslen) sockfd número do socket atribuído anteriormente. sockfd número do socket atribuído anteriormente. *fromaddrptr estrutura que contém o endereço do cliente onde enviar as respostas. *fromaddrptr estrutura que contém o endereço do cliente onde enviar as respostas. Addresslen é o tamanho da estrutura de endereço. Addresslen é o tamanho da estrutura de endereço.

27 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); &other_app_addr, &addrsize); /* newsockid to communicate with client, /* newsockid to communicate with client, sockid to accept more connections */ sockid to accept more connections */

28 Enviando e recebendo dados Os dados são enviados/recebidos usando chamadas E/S do Unix ou chamadas de rede send/recvpara sockets send/recvpara sockets write/readpara qualquer operação de I/O write/readpara qualquer operação de I/O

29 send() int send (int sockfd, char *buff, int bufflen, int flags) sockfd número do socket. sockfd número do socket. *buff é o endereço do dado a ser enviado. O conteúdo abriga a mensagem. *buff é o endereço do dado a ser enviado. O conteúdo abriga a mensagem. bufflen é número de bytes a enviar. bufflen é número de bytes a enviar. flags controla a transmissão. Para nós será sempre 0 (zero). flags controla a transmissão. Para nós será sempre 0 (zero). Obs.: retorna o número de bytes efetivamente enviado.

30 Exemplo: usando send() char buffer[50]; struct sockaddr_in other_app_addr; int retcode /* suppose we have done socket() and bind() calls, filled in other_app_addr,and put 23 bytes of data into buffer */ retcode = send(sockfd, buffer, 23, 0) char buffer[50]; struct sockaddr_in other_app_addr; int retcode /* suppose we have done socket() and bind() calls, filled in other_app_addr,and put 23 bytes of data into buffer */ retcode = send(sockfd, buffer, 23, 0)

31 recv() int recv (int sockfd, char *buff, int bufflen, int flags) sockfd é o número do socket obtido anteriormente. sockfd é o número do socket obtido anteriormente. *buff é o endereço onde o dado será armazenado. *buff é o endereço onde o dado será armazenado. bufflen número máximo esperado bufflen número máximo esperado flags controla a recepção. Esse valor será sempre 0. flags controla a recepção. Esse valor será sempre 0. Obs.: recv() retorna o número de bytes efetivamente recebidos

32 Exemplo: usando recv() char buffer[50]; struct sockaddr_in other_app_addr; int nread, addrlen; /* suppose we have done socket(), bind() */ nread = recv(sockfd, buffer, 23, 0) char buffer[50]; struct sockaddr_in other_app_addr; int nread, addrlen; /* suppose we have done socket(), bind() */ nread = recv(sockfd, buffer, 23, 0)

33 Sockets - outras funções Sockets - estruturas Sockets - estruturas Sockets - funções Sockets - funções Ordenação de bytes e conversões Ordenação de bytes e conversões Serviço não orientado a conexão Serviço não orientado a conexão

34 Sockets - estruturas struct sockaddr {// estrutura parâmetro de connect() unsigned short sa_family; // AF_xxx char sa_data[14]; // IP + porta }; Estrutura paralela para a Internet: Estrutura paralela para a Internet: struct sockaddr_in { short int sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char sin_zero[8]; // pad };

35 Sockets - estruturas struct in_addr { unsigned long s_addr; } sin_port e sin_addr devem estar em Network byte order. (hton x ()), isto é, colocar os bytes em ordem de rede antes de mandá-los pela rede. sin_port e sin_addr devem estar em Network byte order. (hton x ()), isto é, colocar os bytes em ordem de rede antes de mandá-los pela rede. Motivo: são os campos enviados pela rede. Motivo: são os campos enviados pela rede.

36 Ordenação de bytes e conversões

37 Ordenação de Bytes Byte mais significante Byte mais significante chamado de Network byte order (NBO) chamado de Network byte order (NBO) BigEndian BigEndian Byte menos significante Byte menos significante chamado de Host byte order (HBO) chamado de Host byte order (HBO) LittleEndian LittleEndian

38 Rotinas de Ordenação de Byte Rotinas de ordenação de bytes: converte bytes de inteiros para/de 16 e 32-bits de/para Network Byte Order'' Rotinas de ordenação de bytes: converte bytes de inteiros para/de 16 e 32-bits de/para Network Byte Order'' números inteiros devem ser convertido explicitamente para/de Network Byte Order. números inteiros devem ser convertido explicitamente para/de Network Byte Order. computadores diferentes podem armazenar os bytes de inteiros em uma ordem diferente na memória. computadores diferentes podem armazenar os bytes de inteiros em uma ordem diferente na memória. Network Byte Order é dita big-endian Network Byte Order é dita big-endian

39 Big Endian/Little Endian

40 Sockets – funções Se tivermos: struct sockaddr_in ina; ina.sin_addr.s_addr = inet_addr( ); ina.sin_addr.s_addr = inet_addr( ); inet_addr() retorna o endereço em NBO. inet_addr() retorna o endereço em NBO. printf( ´´ %s ´´, inet_ntoa(ina.sin_addr)); printf( ´´ %s ´´, inet_ntoa(ina.sin_addr)); Seqüência de código para aceitar conexões: Seqüência de código para aceitar conexões: socket(); socket(); bind(); bind(); listen(); listen(); accept(); accept();

41 Procedures do UNIX htonlconverte formato de host de 32 bit para nbo; ntohlconverte nbo para o formato host de 32 bit; htons converte formato de host de 16 bit para nbo; ntohs converte nbo para o formato host de 16 bit.

42 Serviço não Orientado a Conexão

43 Serviço não orientado a conexão Serviço de datagrama: o protocolo da camada de transporte não garante a entrega do pacote; Serviço de datagrama: o protocolo da camada de transporte não garante a entrega do pacote; Não há identificação explícita de quem é o servidor e quem é o cliente; Não há identificação explícita de quem é o servidor e quem é o cliente; Ao iniciar o contato com o outro lado precisamos saber: Ao iniciar o contato com o outro lado precisamos saber: o endereço IP; o endereço IP; número da porta onde contactar o outro lado. número da porta onde contactar o outro lado. Ao esperar ser contactado pelo outro lado, precisa declarar Ao esperar ser contactado pelo outro lado, precisa declarar número da porta que está esperando o outro lado número da porta que está esperando o outro lado

44 1.cria o descritor: socket() 2. atribui ao descritor um endereço: bind() 3. Aguarda pkt chegar: recvfrom() 4. Envia resposta(se houver): sendto() 5. Libera o descritor: close() 1. cria o descritor: socket() 2. Atribui ao descritor um endereço: (opcional) bind() 3. determina endereço do servidor 4. envia msg: sendto() 5. Aguarda chegada do pkt : recvfrom() 6. Libera o descritor: close() CLIENTE SERVIDOR

45 Exemplo: Servidor não orientado #include #include #define MY_PORT_ID 6090 /* numero > 5000 */ #define MY_PORT_ID 6090 /* numero > 5000 */ main() { main() { int sockid, nread, addrlen; int sockid, nread, addrlen; struct sockaddr_in my_addr, client_addr; struct sockaddr_in my_addr, client_addr; char msg[50]; char msg[50];

46 Exemplo: Servidor não orientado - cont. printf("Servidor: criando o socket\n"); printf("Servidor: criando o socket\n"); if ( (sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ if ( (sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ printf("Servidor: erro no socket: %d\n",errno); printf("Servidor: erro no socket: %d\n",errno); exit(0); exit(0); } printf("Servidor: Bindando socket local\n"); printf("Servidor: Bindando socket local\n"); bzero((char *) &my_addr, sizeof(my_addr)); bzero((char *) &my_addr, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET; my_addr.sin_addr.s_addr = htons(INADDR_ANY); my_addr.sin_addr.s_addr = htons(INADDR_ANY); my_addr.sin_port = htons(MY_PORT_ID); my_addr.sin_port = htons(MY_PORT_ID);

47 if ( (bind(sockid, (struct sockaddr *) &my_addr, if ( (bind(sockid, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) ){ sizeof(my_addr)) < 0) ){ printf("Servidor: falha no binding : printf("Servidor: falha no binding :%d\n",errno); exit(0); exit(0); } printf("Servidor: iniciando bloqueio de mensagem lida\n"); printf("Servidor: iniciando bloqueio de mensagem lida\n"); nread = recvfrom(sockid,msg,11,0, nread = recvfrom(sockid,msg,11,0, (struct sockaddr *) &client_addr, &addrlen); (struct sockaddr *) &client_addr, &addrlen); printf("Servidor: cod retorno lido é %d\n",nread); printf("Servidor: cod retorno lido é %d\n",nread); if (nread >0) printf("Servidor: mensagem é : if (nread >0) printf("Servidor: mensagem é : %.11s\n",msg); %.11s\n",msg); close(sockid); close(sockid); } Exemplo: Servidor não orientado - cont.

48 Exemplo: Cliente não orientado #include #include #define MY_PORT_ID 6089 #define MY_PORT_ID 6089 #define SERVER_PORT_ID 6090 #define SERVER_PORT_ID 6090 #define SERV_HOST_ADDR " " #define SERV_HOST_ADDR " " main() { main() { int sockid, retcode; int sockid, retcode; struct sockaddr_in my_addr, server_addr; struct sockaddr_in my_addr, server_addr; char msg[12]; char msg[12];

49 printf("Cliente: criando socket\n"); printf("Cliente: criando socket\n"); if ((sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ if ((sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ printf("Cliente: falha no socket: %d\n",errno); printf("Cliente: falha no socket: %d\n",errno); exit(0); exit(0); } printf("Cliente: amarrando socket local\n"); printf("Cliente: amarrando socket local\n"); bzero((char *) &my_addr, sizeof(my_addr)); bzero((char *) &my_addr, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET; my_addr.sin_addr.s_addr = htonl(INADDR_ANY); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); my_addr.sin_port = htons(MY_PORT_ID); my_addr.sin_port = htons(MY_PORT_ID); if ( ( bind(sockid, (struct sockaddr *) &my_addr, if ( ( bind(sockid, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) ){ sizeof(my_addr)) < 0) ){ printf("Cliente: falha no bind : %d\n",errno); printf("Cliente: falha no bind : %d\n",errno); exit(0); exit(0); } Exemplo: Cliente não orientado - cont.

50 Printf("Cliente: criando estrutura addr para Printf("Cliente: criando estrutura addr para o servidor\n"); o servidor\n"); bzero((char *) &server_addr, sizeof(server_addr)); bzero((char *) &server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = server_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); inet_addr(SERV_HOST_ADDR); server_addr.sin_port = htons(SERVER_PORT_ID); server_addr.sin_port = htons(SERVER_PORT_ID); printf("Cliente: iniciando mensagem e printf("Cliente: iniciando mensagem e enviando\n"); enviando\n"); sprintf(msg, Ola para todos"); sprintf(msg, Ola para todos"); retcode = sendto(sockid,msg,12,0,(struct retcode = sendto(sockid,msg,12,0,(struct sockaddr *)&server_addr, sockaddr *)&server_addr,sizeof(server_addr)); if (retcode <= -1){ if (retcode <= -1){ printf("cliente: falha no sendto: %d\n",errno); printf("cliente: falha no sendto: %d\n",errno); exit(0); exit(0); } /* close socket */ /* close socket */ close(sockid); close(sockid); }

51 Resumo do Fluxograma TCP / UDP TCP / UDP

52

53 Uma aplicação de tempo simples: Cliente: conecta ao servidor conecta ao servidor envia ao servidor a sua hora local envia ao servidor a sua hora local lê de volta a hora do servidor lê de volta a hora do servidorServidor: recebe conexões dos clientes recebe conexões dos clientes imprime a hora local do cliente imprime a hora local do cliente envia ao cliente a sua hora local envia ao cliente a sua hora local

54 Uma aplicação de tempo simples: código cliente 1 #include 1 #include 2 #include 2 #include 3 #include 3 #include 4 #include 4 #include 5 #include 5 #include 6 #include 6 #include 7 #define SERV_HOST_ADDR " " /* Don's host machine */ 8 main() 9 { 10 int sockid; 11 struct sockaddr_in ssock_addr; 12 struct timeval tp; 13 struct timezone tzp;

55 15 /* create a socket */ 16 if ((sockid = socket( AF_INET,SOCK_STREAM, 0 )) < 0){ 17 printf("erro criacao=%d",errno); 18 exit(0); 19 } 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); 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){ &server_addr, sizeof(server_addr)) < 0){ 27 printf("error connecting to server, error: %d \n ",errno); 28 exit(0); 29 }

56 30 /* send time of day */ 31 gettimeofday(&tp,&tzp); 32 /* convert from host byte order to network byte order */ 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

57 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 }

58 Aplicação de tempo: código servidor 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define MY_PORT_ID main() 11 { 12 int sockid, newsockid, i,j; 13 struct sockaddr_in ssock_addr; 14 struct timeval tp; 15 struct timezone tzp; 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define MY_PORT_ID main() 11 { 12 int sockid, newsockid, i,j; 13 struct sockaddr_in ssock_addr; 14 struct timeval tp; 15 struct timezone tzp;

59 17 if ( (sockid = socket (AF_INET, SOCK_STREAM, 0)) < 0) 18 { printf("erro criacao= %d \n ",errno); exit(0);} /* man errno */ 19 /* name the socket using wildcards */ 20 bzero((char *) &ssock_addr, sizeof(ssock_addr)); 21 ssock_addr.sin_family = AF_INET; 22 ssock_addr.sin_addr.s_addr = htonl(INADDR_ANY); 23 ssock_addr.sin_port = htons(MY_PORT_ID); 24 /* bind the socket to port address */ 25 if ( ( bind(sockid, (struct sockaddr *) &ssock_addr,sizeof(ssock_addr))< 0)) 26 { printf("error binding socket, error: %d ",errno); exit(0); } %d \n ",errno); exit(0); } 29 /* start accepting connections */ 30 if ( listen (sockid, 5) < 0) 31 { printf("erro listening: %d \n ",errno); exit(0); }

60 33 for (i=1; i<=50000 ;i++) { 34 /* accept a connection */ 35 newsockid = accept(sockid, (struct sockaddr *)0, (int *)0); 36 if (newsockid < 0) 37 { printf("error accepting socket, error: %d ",errno); exit(0); } error: %d \n ",errno); exit(0); } 38 /* le tempo remoto */ 39 if ( (read(newsockid, &tp, sizeof(tp))) < 0) 40 { printf("error reading new socket "); exit(0); } \n "); exit(0); } 41 /* convert from network byte order to host byte order */ 42 tp.tv_sec = ntohl(tp.tv_sec); 43 tp.tv_usec = ntohl(tp.tv_usec); 44 printf("server: remote time is %ld ",tp.tv_sec); %ld \n ",tp.tv_sec);

61 46 /* get local time of day and send to client*/ 47 for (j=0; j< ; j++); 48 /* delay */ 49 gettimeofday(&tp,&tzp); 50 /* convert from host byte order to network byte order */ 51 printf("server: local time is %ld ",tp.tv_sec); %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 }

62 Bibliografia COMER, Douglas E. InternetWorking with TCP/IP -VOL 1. COMER, Douglas E. InternetWorking with TCP/IP -VOL 1. Tutorial sobre sockets: Tutorial sobre sockets: Sockets em Java: efinition.html


Carregar ppt "Comunicação entre processos usando Sockets Disciplina: Linguagem de Programação IV."

Apresentações semelhantes


Anúncios Google