Escolar Documentos
Profissional Documentos
Cultura Documentos
06 Comunicacao
06 Comunicacao
•Canal de comunicação
•Arquitectura da comunicação
•Modelos de comunicação
Sistemas Operativos
1
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Sistemas Operativos
2
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 1
Comunicação entre Processos
Processo Processo
Produtor Mensagem
Consumidor
Enviar Receber
Canal de Comunicação
Canal de Comunicação
Sistemas Operativos
4
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 2
Arquitectura da Comunicação:
memória partilhada
Espaço de endereçamento
do processo P2
Espaço de endereçamento
do processo P1
Sistemas Operativos
5
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Arquitectura da Comunicação:
cópia através do núcleo
Sistemas Operativos
6
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 3
Memória Partilhada
Sistemas Operativos
7
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Objecto de Comunicação do
Sistema
• IdCanal = CriarCanal(Nome)
• IdCanal = AssociarCanal (Nome)
• EliminarCanal (IdCanal)
• Enviar (IdCanal, Mensagem)
• Receber (IdCanal, Mensagem)
Page 4
Comparação: memória partilhada
vs. cópia através do núcleo
Sistemas Operativos
9
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Resumo do Modelo
Computacional
• memória partilhada:
– Endereço = CriarRegião ( Nome, Dimensão )
– Endereço = AssociarRegião ( Nome )
– EliminarRegião ( Endereço )
• caixas do correio:
– IdCC = CriarCCorreio ( Nome, Parâmetros )
– IdCC = AssociarCCorreio ( Nome )
– EliminarCCorreio ( IdCC )
• ligações virtuais (para suporte ao diálogo):
– IdCanalServidor = CriarCanal ( Nome )
– IdCanal = EsperarLigação ( IdCanalServidor )
– IdCanal = PedirLigação ( Nome )
Sistemas Operativos
10
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 5
Unix– Modelo Computacional - IPC
• pipes
• sockets
• memória partilhada
Bibliografia:
• Unix Network Programming (Caps. 3 e 6)
• Fundamentos de Sistemas Operativos
Sistemas Operativos
11
Comunicação JAM, PJG, PF, CNR, JCCC, RR
PIPES
Sistemas Operativos
12
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 6
Sistema de Ficheiros
Sistemas Operativos
13
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Sistema de Ficheiros
main (argc, argv)
int argc;
char *argv[];
{
int origem, destino, n;
char buffer[1024];
Page 7
Sistema de Ficheiros UNIX
Process
program program
FILE* iobuf FILE* iobuf
stdio stdio
flush flush
open/read/write/close open/read/write/close
USER FILE DESCRIPTOR TABLE USER FILE DESCRIPTOR TABLE
Inode TABLE
CACHE
sync
DISCO
Sistemas Operativos
15
Comunicação JAM, PJG, PF, CNR, JCCC, RR
IPC no UNIX
• Mecanismo inicial:
– pipes
• Extensão dos pipes:
– pipes com nome
• Evolução do Unix BSD 4.2:
– sockets
Bibliografia:
•Unix Network Programming (Caps. 3 e 6)
Sistemas Operativos
•Fundamentos de Sistemas Operativos
16
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 8
Pipes
sistema operativo
Pipes
Page 9
Pipes
main() {
char tampao[1024];
int fds[2];
pipe(fds);
for (;;) {
write (fds[1], msg, sizeof (msg));
read (fds[0], tampao, sizeof (msg)));
}
}
Sistemas Operativos
19
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Pipes
Processo Utilizador
read fds
write fds
pipe
Sistemas Operativos
20
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 10
Comunicação pai-filho
#include <stdio.h> }
#include <fnctl.h> else {
#define TAMSG 100 /* processo pai */
char msg[] = “mensagem de teste”; /* escreve no pipe */
char tmp[TAMSG]; write (fds[1], msg,
sizeof (msg));
pid_filho = wait();
main() {
}
int fds[2], pid_filho;
}
if (pipe (fds) < 0) exit(-1);
if (fork () == 0) {
/* lê do pipe */
read (fds[0], tmp, sizeof (msg));
printf (“%s\n”, tmp);
exit (0);
Sistemas Operativos
21
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Antes Depois
fd2 fd2
Sistemas Operativos
22
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 11
DUP – System Call
• dup2(fd1, fd2) faz de fd2 uma cópia de fd1, fechando fd2 se
necessário
Antes Depois
Redireccionamento de
Entradas/Saídas
#include <stdio.h> /* fecha os descritores não usados pelo
#include <fnctl.h> filho */
#define TAMSG 100 close (fds[0]);
char msg[] = “mensagem de teste”; close (fds[1]);
char tmp[TAMSG];
/* lê do pipe */
read (0, tmp, sizeof (msg));
main() {
printf (“%s\n”, tmp);
int fds[2], pid_filho;
exit (0);
if (pipe (fds) < 0) exit(-1); }
if (fork () == 0) { else {
/* processo filho */ /* processo pai */
/* liberta o stdin (posição zero) */ /* escreve no pipe */
close (0); write (fds[1], msg, sizeof (msg));
pid_filho = wait();
/* redirecciona o stdin para o pipe }
de leitura */
}
dup (fds[0]);
Sistemas Operativos
24
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 12
Redireccionamento de
Entradas/Saídas (cont.)
pai filho
stdin stdin
stdout stdout close (0)
dup (fds[0]);
close (1); stderr stderr close (fds[0]);
dup (fds[1]); close (fds[1]);
close (fds[0]); fds[0] fds[0]
read (0, ...);
close (fds[1]);
fds[1] fds[1]
write (1, ...);
Sistemas Operativos
25
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Redireccionamento de
Entradas/Saídas (cont.)
exemplo:
who | sort | lpr
write fd
sistema operativo
pipe 1 pipe 2
Sistemas Operativos
26
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 13
popen
Sistemas Operativos
27
Comunicação JAM, PJG, PF, CNR, JCCC, RR
popen (cont.)
EXEMPLO: Escrever no standard output a lista de
ficheiros *.c
#include <stdio.h>
#include <stdlib.h>
main() {
char *cmd = "/usr/bin/ls *.c";
char buf[BUFSIZ];
FILE *ptr;
Page 14
popen (cont.)
pai filho pai filho
#include <stdio.h>
Sistemas Operativos
31
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 15
Pipes com Nome
Sistemas Operativos
32
Comunicação JAM, PJG, PF, CNR, JCCC, RR
/* Servidor */
/* Cliente */
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#define TAMMSG 1000 #define TAMMSG 1000
Page 16
Sockets
Sistemas Operativos
34
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Sistemas Operativos
35
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 17
Domínio e Tipo de Sockets (II)
SOCK_RAW - IP SIM
SOCK_SEQPACKET - - SPP
Sistemas Operativos
36
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Sistemas Operativos
37
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 18
Sockets sem Ligação
Servidor Cliente
socket socket
bind bind
sendto
recvfrom
sendto
recvfrom
Sistemas Operativos
38
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Servidor Cliente
socket
bind
listen socket
accept connect
read write
write read
Sistemas Operativos
39
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 19
Interface Sockets: definição dos
endereços
/* ficheiro <sys/socket.h> */ /* ficheiro <netinet/in.h> */
struct sockaddr { struct in_addr {
u_short family; /* definição do dominio u_long addr; /* Netid+Hostid */
(AF_XX)*/
char sa_data[14]; /* endereço específico
};
do dominio*/
}; struct sockaddr_in {
/* ficheiro <sys/un.h> */
u_short sin_family; /* AF_INET */
struct sockaddr_un { u_short sin_port; /* no. porto - 16 bits*/
u_short family; /* definição do struct in_addr sin_addr; /* IP addr */
domínio (AF_UNIX) */ char sin_zero[8]; /* não utilizado*/
char sun_path[108]; /* nome */ };
};
struct sockaddr struct sockaddr_un struct sockaddr_in
family family family
2-byte port
Endereço específico pathname 4-byte net ID, host ID
do domínio (up to 108 bytes) (unused)
Sistemas Operativos
40
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Sistemas Operativos
41
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 20
Sockets sem Ligação
Sistemas Operativos
42
Comunicação JAM, PJG, PF, CNR, JCCC, RR
unix.h e inet.h
inet.h
unix.h
#include <stdio.h>
#include <stdio.h> #include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
#include <arpa/inet.h>
#define UNIXSTR_PATH
"/tmp/s.unixstr"
#define UNIXDG_PATH #define SERV_UDP_PORT 6600
"/tmp/s.unixdgx" #define SERV_TCP_PORT 6601
#define UNIXDG_TMP #define SERV_HOST_ADDR "193.136.128.20 “
"/tmp/dgXXXXXXX" /* endereço do servidor */
#define SERV_HOSTNAME “mega"
/* nome do servidor */
Sistemas Operativos
43
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 21
Servidor DGRAM AF_UNIX
/* Servidor do tipo socket datagram. Recebe linhas do cliente e devolve-as para o cliente */
#include "unix.h"
main (void) {
int sockfd, servlen;
struct sockaddr_un serv_addr, cli_addr;
/* Cria socket datagram */
if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
err_dump("server: can't open datagram socket");
unlink(UNIXDG_PATH);
Page 22
Cliente DGRAM AF_UNIX
#include "unix.h"
main(void) {
int sockfd, clilen, servlen;
char *mktemp();
struct sockaddr_un cli_addr, serv_addr;
Sistemas Operativos
46
Comunicação JAM, PJG, PF, CNR, JCCC, RR
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, UNIXDG_PATH);
servlen=sizeof(serv_addr.sun_family) +
strlen(serv_addr.sun_path);
close(sockfd);
unlink(cli_addr.sun_path);
exit(0);
}
Sistemas Operativos
47
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 23
Cliente DGRAM AF_UNIX (III)
#include <stdio.h>
#define MAXLINE 512
#include <sys/types.h>
#include <sys/socket.h>
Page 24
Sockets com Ligação
Sistemas Operativos
50
Comunicação JAM, PJG, PF, CNR, JCCC, RR
unix.h e inet.h
inet.h
unix.h
#include <stdio.h>
#include <stdio.h> #include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
#include <arpa/inet.h>
#define UNIXSTR_PATH
"/tmp/s.unixstr"
#define UNIXDG_PATH #define SERV_UDP_PORT 6600
"/tmp/s.unixdgx" #define SERV_TCP_PORT 6601
#define UNIXDG_TMP #define SERV_HOST_ADDR "193.136.128.20 “
"/tmp/dgXXXXXXX" /* endereço do servidor */
#define SERV_HOSTNAME “mega"
/* nome do servidor */
Sistemas Operativos
51
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 25
Servidor STREAM AF_UNIX (main)
/* Recebe linhas do cliente e reenvia-as para o servlen = strlen(serv_addr.sun_path) +
cliente */ sizeof(serv_addr.sun_family);
#include "unix.h" if (bind(sockfd, (struct sockaddr *)
&serv_addr, servlen) < 0)
main(void) { err_dump("server, can't bind local address");
int sockfd, newsockfd, clilen, childpid, servlen; listen(sockfd, 5);
struct sockaddr_un cli_addr, serv_addr; for (;;) {
clilen = sizeof(cli_addr);
/* Cria socket stream */ newsockfd = accept(sockfd,(struct sockaddr *)
if((sockfd = socket(AF_UNIX,SOCK_STREAM,0) ) < 0) &cli_addr, &clilen);
err_dump("server: can't open stream socket"); if(newsockfd<0)
err_dump("server: accept error");
/* O nome serve para que os clientes possam /*Lança processo filho para tratar com o cliente*/
identificar o servidor */ if ((childpid = fork()) < 0)
bzero((char *)&serv_addr, sizeof(serv_addr)); err_dump("server: fork error");
serv_addr.sun_family = AF_UNIX; else if (childpid == 0) {
strcpy(serv_addr.sun_path, UNIXSTR_PATH); /* Código do filho */
close(sockfd); // Não é utilizado pelo filho
/* Elimina o ficheiro, para o caso de algo ter str_echo(newsockfd);
ficado pendurado. exit(0);
unlink(UNIXSTR_PATH); }
/* Código do pai */
close(newsockfd); // Não é utilizado pelo pai
} // for } // main
Sistemas Operativos
52
Comunicação JAM, PJG, PF, CNR, JCCC, RR
for (;;) {
/* Lê uma linha do socket */
n = readline(sockfd, line, MAXLINE);
if (n == 0) return;
else if (n < 0)
err_dump("str_echo: readln err");
Sistemas Operativos
53
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 26
Cliente STREAM AF_UNIX (main)
/* Cliente do tipo socket stream.
#include "unix.h" /*Estabelece uma ligação. Só funciona se o
main(void) { sockt tiver sido criado e o nome associado*/
int sockfd, servlen; if(connect(sockfd, (struct sockaddr *)
struct sockaddr_un serv_addr;
&serv_addr, servlen) < 0)
/* Cria socket stream */
err_dump("clnt:can't connect to serv");
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, UNIXSTR_PATH);
servlen = strlen(serv_addr.sun_path) +
sizeof(serv_addr.sun_family);
Sistemas Operativos
54
Comunicação JAM, PJG, PF, CNR, JCCC, RR
} /* while */
if (ferror(fp))
err_dump("str_cli: err read file");
}
Sistemas Operativos
55
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 27
Utilitários
/* Escreve nbytes num ficheiro/socket. /* Lê uma linha de até \n, maxlen ou \0.
Bloqueia até conseguir escrever os Bloqueia até ler a linha ou dar erro.
nbytes ou dar erro */
int writen(int fd, char* ptr, int nbytes){ Retorna quantos caracteres conseguiu ler */
int nleft, nwritten; int readline(int fd, char* ptr, int maxlen) {
nleft = nbytes; int n, rc; char c;
while (nleft > 0) { for (n=1; n < maxlen; n++) {
nwritten = write(fd, ptr, nleft); if ((rc = read(fd, &c, 1)) == 1) {
if (nwritten <= 0) return(nwritten); *ptr++ = c;
nleft -= nwritten; if (c == '\n') break;
ptr += nwritten;
} else if (rc == 0) {
}
return(nbytes - nleft); if (n == 1) return(0);
} else break;
} else return (-1);
}
#include <stdio.h> /* Não esquecer de terminar a string */
#include <errno.h> *ptr = 0;
/* Mensagem de erro */ /* Note-se que n foi incrementado de modo a contar
err_dump(char* msg) { com o \n ou \0 */
perror(msg); return (n);
exit(1); }
}
Sistemas Operativos
56
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Sistemas Operativos
57
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 28
Espera Múltipla com Select (cont.)
struct timeval {
long tv_sec; /* seconds /*
tv_usec; /* microseconds /*
}
• esperar para sempre (alarme é null pointer)
• esperar um intervalo de tempo fixo (alarme com o tempo
respectivo)
• não esperar (alarme com valor zero nos segundos e
microsegundos)
Sistemas Operativos
58
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Manipulação do fd_set
Sistemas Operativos
59
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 29
Servidor com Select
/* Servidor que utiliza sockets stream e
datagram em simultâneo. int main(void) {
O servidor recebe caracteres e envia-os int strmfd,dgrmfd,newfd;
para stdout */ struct sockaddr_un servstrmaddr,servdgrmaddr,clientaddr;
int len,clientlen;
#include <stdio.h> fd_set testmask,mask;
#include <sys/types.h>
#include <sys/time.h> /* Cria socket stream */
#include <sys/socket.h> if((strmfd=socket(AF_UNIX,SOCK_STREAM,0))<0){
#include <sys/un.h> perror(ERRORMSG1);
#include <errno.h> exit(1);
}
bzero((char*)&servstrmaddr,
#define MAXLINE 80
sizeof(servstrmaddr));
#define MAXSOCKS 32
servstrmaddr.sun_family = AF_UNIX;
strcpy(servstrmaddr.sun_path,UNIXSTR_PATH);
#define ERRORMSG1 "server: cannot open stream len = sizeof(servstrmaddr.sun_family)
socket" +strlen(servstrmaddr.sun_path);
#define ERRORMSG2 "server: cannot bind stream unlink(UNIXSTR_PATH);
socket" if(bind(strmfd,(struct sockaddr *)&servstrmaddr, len)<0)
#define ERRORMSG3 "server: cannot open {
datagram socket" perror(ERRORMSG2);
#define ERRORMSG4 "server: cannot bind exit(1);
datagram socket"
Sistemas Operativos }
#include "names.h" 60
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 30
Servidor com Select (III)
for(;;) {
mask = testmask;
Sistemas Operativos
62
Comunicação JAM, PJG, PF, CNR, JCCC, RR
unix.h e inet.h
inet.h
unix.h
#include <stdio.h>
#include <stdio.h> #include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
#include <arpa/inet.h>
#define UNIXSTR_PATH
"/tmp/s.unixstr"
#define UNIXDG_PATH #define SERV_UDP_PORT 6600
"/tmp/s.unixdgx" #define SERV_TCP_PORT 6601
#define UNIXDG_TMP #define SERV_HOST_ADDR "193.136.128.20 “
"/tmp/dgXXXXXXX" /* endereço do servidor */
#define SERV_HOSTNAME “mega"
/* nome do servidor */
Sistemas Operativos
63
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 31
Servidor UDP AF_INET
/* Servidor do tipo socket udp (datagram). /* Associa o socket a qualquer clnt */
Recebe linhas do clnt e devolve-as para o clnt */ if (bind(sockfd,
(struct sockaddr *)&serv_addr,
#include "inet.h"
sizeof(serv_addr)) < 0)
err_dump("server: bind");
main(void) {
int sockfd;
/* Fica à espera de msgs do cliente.
struct sockaddr_in serv_addr, cli_addr;
As msgs recebidas são reenviadas */
/* Cria socket udp (datagram) */ dg_echo(sockfd,
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) (struct sockaddr *)&cli_addr,
err_dump("server: can't open datagram sizeof(cli_addr));
socket"); }
#include <sys/types.h>
/* Lê uma linha do socket */
#include <sys/socket.h> n = recvfrom(sockfd, mesg, MAXMESG, 0,
pcli_addr, &clilen);
#define MAXMESG 2048
if (n < 0) err_dump("dg_echo: recvfrom err");
/* pcli_addr especifica o cliente */
/* Manda linha de volta para o socket */
dg_echo(sockfd, pcli_addr, maxclilen)
if ( sendto(sockfd, mesg, n, 0,
int sockfd;
struct sockaddr *pcli_addr; pcli_addr, clilen) != n)
int maxclilen; err_dump("dg_echo: sendto err");
{
}
int n, clilen;
char mesg[MAXMESG]; }
Sistemas Operativos
65
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 32
Cliente UDP AF_INET
/* Cria socket udp (datagram) */
/* Cliente do tipo socket udp (datagram). if ((sockfd = socket(AF_INET, SOCK_DGRAM,
Lê linhas de stdin, envia para o servidor,
recebe-as 0)) < 0)
de novodo servidor e envia-as para stdout */ err_dump("clnt: datagram socket");
#include "inet.h" /* Associa o socket a qualquer endereço. Esta
associação serve para ter um socket funcional mas
main(void) { não ligado a um servidor */
int sockfd; bzero((char*)&cli_addr, sizeof(cli_addr));
struct sockaddr_in cli_addr, serv_addr; cli_addr.sin_family = AF_INET;
struct hostent *hp;
cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* Primeiro uma limpeza preventiva! cli_addr.sin_port = htons(0);
Dados para o socket udp (datagram): tipo */ if (bind(sockfd, (struct sockaddr *)&cli_addr,
bzero((char*)&serv_addr, sizeof(serv_addr)); sizeof(cli_addr)) < 0)
serv_addr.sin_family = AF_INET; err_dump(“clnt: bind");
/* Lê linha do stdin e envia para o server. Recebe
/* Obter endereço do servidor a partir do nome a linha do serv e envia-a para stdout */
*/
dg_cli(stdin,sockfd,(struct sockaddr*)&serv_addr,
hp = gethostbyname(SERV_HOSTNAME); sizeof(serv_addr));
Sistemas Operativos
66
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 33
Servidor TCP AF_INET
/* Servidor do tipo socket tcp (stream).
Recebe linhas do cliente e reenvia-as para o cliente */ /* Servidor pronto a aceitar 5 clientes para o socket tcp (stream) */
#include "inet.h" listen(sockfd, 5);
main(void) { for ( ; ; ) {
int sockfd, newsockfd, clilen, childpid; /* Não esquecer que quando o servidor aceita um cliente
struct sockaddr_in cli_addr, serv_addr; cria um socket para comunicar com ele; o primeiro
socket (sockfd) fica à espera de mais clientes */
/* Cria socket stream */ clilen = sizeof(cli_addr);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr,
err_dump("server: can't open socket"); &clilen);
if (newsockfd < 0) err_dump("server: accept error");
/* Primeiro uma limpeza preventiva; dados para o
/* Lança processo filho para lidar com o cliente */
socket stream: tipo + qualquer endereço; note-se
que o servidor aceita qualquer endereço de cliente */ else if ((childpid = fork()) < 0) err_dump("server: fork error");
else if (childpid == 0) {
bzero((char*)&serv_addr, sizeof(serv_addr)); /* Processo filho que vai atender o cliente; fechar
serv_addr.sin_family = AF_INET; sockfd é indicado, já que não é utilizado pelo
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); processo filho; os dados recebidos do cliente
são reenviados para o cliente */
serv_addr.sin_port = htons(SERV_TCP_PORT);
close (sockfd);
str_echo(newsockfd);
/* Associa o socket (a qualquer endereço de cliente) */
exit(0);
if (bind(sockfd, (struct sockaddr *)&serv_addr, }
sizeof(serv_addr)) < 0)
err_dump("server: can't bind local address"); /* Processo pai; fechar newsockfd é indicado, já que não é
Sistemas Operativos utilizado pelo processo pai */
close (newsockfd); 68
Comunicação JAM, PJG, PF, CNR, JCCC, RR
}
}
str_echo(int sockfd) {
int n;
char line[MAXLINE];
for (;;) {
/* Lê uma linha do socket */
n = readline(sockfd, line, MAXLINE);
if (n == 0) return;
else if (n < 0) err_dump("str_echo: readline error");
Page 34
Cliente TCP AF_INET
/* Cliente do tipo socket tcp (stream). /* Dados para o socket stream: informação sobre o servidor */
Lê linhas do teclado e envia-as para o servidor */ bcopy (hp->h_addr_list[0], (char*)&serv_addr.sin_addr.s_addr,
hp->h_length);
#include "inet.h" serv_addr.sin_port = htons(SERV_TCP_PORT);
Sistemas Operativos
71
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 35
Ordenação de Bytes
• htonl:
– convert host-to-network, long integer
• htons:
– convert host-to-network, short integer
• ntohl:
– convert network-to-host, long integer
• ntohs:
– convert network-to-host, short integer
Sistemas Operativos
72
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Sistemas Operativos
73
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 36
Memória Partilhada
Page 37
Exemplo: Memória Partilhada
/* consumidor*/ main() {
IdRegPart = shmget (CHAVEMEM, 1024, 0777);
if (IdRegPart <0)
#include <stdio.h>
perror("shmget:");
#include <sys/types.h>
#include <sys/ipc.h> Apint=(int*)shmat(IdRegPart, (char *)0, 0);
#include <sys/shm.h> if(Apint == (int *) -1)
perror("shmat:");
#define CHAVEMEM 10
printf(" mensagem na regiao de memoria partilhada \n");
int IdRegPart; for (i = 0; i<256; i++)
int *Apint; printf ("%d ", *Apint++);
int i;
printf (" \n liberta a regiao partilhada \n");
shmctl (IdRegPart, 0, IPC_RMID,0);
}
Sistemas Operativos
76
Comunicação JAM, PJG, PF, CNR, JCCC, RR
main () {
/* produtor */
IdRegPart = shmget (CHAVEMEM, 1024, 0777| IPC_CREAT);
if (IdRegPart<0) perror(" shmget:");
#include <stdio.h>
#include <sys/types.h>
printf (" criou uma regiao de identificador %d \n",
#include <sys/ipc.h>
IdRegPart);
#include <sys/shm.h>
Sistemas Operativos
77
Comunicação JAM, PJG, PF, CNR, JCCC, RR
Page 38