Aula 3 - Professor Diovani
Download
Report
Transcript Aula 3 - Professor Diovani
Redes de computadores II
Comunicação entre processos
Prof. Diovani Milhorim
Comunicação entre processos
Troca de mensagens
Sockets (cliente/servidor)
RPC (remote procedure call)
Comunicação entre processos
Troca de mensagens
Síncrona
Assíncrona
Unidirecional
Bidirecional
Comunicação entre processos
Troca de mensagens unidirecional
A comunicação de dados entre processos é
chamada de unidirecional quando um dos
processos sempre envia mensagens para um
outro processo.
Comunicação entre processos
Troca de mensagens bidirecional
A comunicação de dados entre processos é
chamada de bidirecional quando qualquer
um dos processos pode enviar ou receber
mensagens entre eles.
Comunicação entre processos
Troca de mensagens
Podemos definir duas entidades na troca de
mensagens:
Emissor
Receptor
Comunicação entre processos
Troca de mensagens
Emissor : Entidade que envia as mensagens.
No caso de comunicação bidirecional o processo
pode assumir tanto o papel de emissor quanto de
receptor. No caso de comunicação unidirecional, um
processo sempre será emissor e outro sempre o
receptor.
Comunicação entre processos
Troca de mensagens síncrona
Na comunicação síncrona, o processo
emissor fica suspenso esperando que o
receptor receba a mensagem. É comum que
continue bloqueado até réplica do receptor
Comunicação entre processos
Troca de mensagens síncrona
Não existe necessidade de bufferização
Não existe necessidade de mecanismo extra
para sincronizar.
Maior risco de deadlock.
Comunicação entre processos
Troca de mensagens assíncrona
Os processos nunca ficam bloqueados. Um
processo A envia mensagem para o
processo B e continua o seu processamento
normalmente. O receptor, na hora que
desejar ler a mensagem, realiza sua
recepção e também continua seu
processamento normal.
Comunicação entre processos
Troca de mensagens assíncrona
Existência de bufferização
Ausência de bloqueios
Inexistência de deadlocks.
Maior modularidade e escalabilidade de
aplicativos.
Ausência de sincronismo.
Comunicação entre processos
Estrutura de comunicação entre processos.
Pipes: Funcionam com tubulações, o que se
coloca de um lado segue sequencialmente
para o outro lado.
Pipes anônimos.
Pipes nomeados.
Comunicação entre processos
Estrutura de comunicação entre processos.
Pipes anônimos.
Mecanismo arcaico de comunicação entre
processos. É sempre unidirecional, local, e
síncrono.
Ex. Comandos em seqüência do bash.
Comunicação entre processos
Estrutura de comunicação entre processos.
Pipes anônimos.
Permite apenas comunicação unidirecional. Se um processo está
tentando passar os dados, e o leitor ainda não está pronto, o pipe
bloqueia o processo até que o mesmo esteja disponível. Sendo assim,
o próprio pipe provê a sincronização dos processos. Os pipes só
podem se comunicar entre processos “parent – child”, por exemplo,
comandos executados em um mesmo terminal.
Ex : cat /etc/passwd | more
Comunicação entre processos
Estrutura de comunicação entre processos.
Pipes nomeados.
Um pipe nomeado é uma extensão do pipe convencional. A diferença é
que um pipe termina juntamente com o fim da execução do programa,
e um pipe nomeado deve ser criado e destruido explicitamente.
Para criar um pipe nomeado pode-se usar o comando mknod ou
mkfifo.
Pode-se usar pipes nomeados em programas para prover meios de
comunicação inter processos.
É bidirecional, local ou remoto. Pode ser síncrono ou
assíncrono. Diversas instâncias de um pipe podem ser criadas, uma
para cada cliente.
Ex. em bash : #mknod ou mkfifo
Comunicação entre processos
Pipes nomeados.
Exemplo:
#mkfifo teste
#cat < teste
O pipe fica esperando até obter algum dado
Em outro terminal execute:
#ls > teste
A saída do comando ls será redirecionada para o pipe nomeado “teste”
Desta forma, a saída do comando ls será ecoada no primeiro terminal,
o qual aguardava recebimento de dados no pipe.
Comunicação entre processos
Sockets:
Uma interface local, criada e possuida pelas
aplicações, controlada pelo S.O. atráves do
qual os processos podem trocar mensagens.
Comunicação entre processos
Sockets:
Comunicação entre processos que se utiliza das
funcionalidades dos protocolos de rede para
realizar a troca de informações entre emissor e
receptor.
Comunicação entre processos
Sockets:
A programação por portas (sockets) se utiliza
dos serviços de redes, sejam eles orientados
ou não orientados a conexão.
Comunicação entre processos
Sockets:
Interface padrão para comunicação entre processos em redes
TCP/IP
Nasceu com o Unix de Berkeley
Os projetistas tentaram usar ao máximo as chamadas de
sistema do Unix
Implementada hoje em vários Sos
Programar com sockets pode ser visto como desenvolver um
protocolo de aplicação
Comunicação entre processos
Sockets:
Um socket pode ser entendido como uma porta de um canal de
comunicação que permite a um processo executando em um
computador enviar/receber mensagens para/de outro processo que
pode estar sendo executado no mesmo computador ou num
computador remoto.
Comunicação entre processos
Sockets:
Abaixo temos uma figura com que representa a comunicação de
sockets e a pilha TCP/IP
Comunicação entre processos
Sockets:
Comunicação entre processos
Sockets:
Comunicação entre processos
Sockets:
Comunicação entre processos
Sockets:
Os sockets permitem então a comunicação processo a
processo da seguinte forma :
comunicação local : processos locais usando sockets
locais
comunicação remota : processos remotos usando sockets
em rede (TCP/IP)
Comunicação entre processos
Sockets:
Tipos de serviço de transporte:
Datagrama - transporte não orientado a conexão e sem
controle de erros ( protocolo UDP)
DataStream - transporte orientado a conexão com
controle de erros ( protocolo TCP )
Raw – baixo nível – pacotes IP
Comunicação entre processos
Sockets:
Serviço com conexão
Serviço sem conexão
Implementa um stream de dados (SOCK_STREAM)
Protocolo TCP (tipicamente)
Implementa um serviço de datagramas (SOCK_DGRAM)
Protocolo UDP (tipicamente)
Acessa diretamente a camada de rede (SOCK_RAW)
Serviço de baixo nível
Protocolo IP (tipicamente)
Comunicação entre processos
Sockets: Principais funções da API
socket
connect
write
read
close
bind
listen
Cria um novo descritor para comunicação
Iniciar conexão com servidor
Escreve dados em uma conexão
Lê dados de uma conexão
Fecha a conexão
Atribui um endereço IP e uma porta a um socket
Coloca o socket em modo passivo, para “escutar”
portas
Bloqueia o servidor até chegada de requisição de
accept
conexão
recvfrom Recebe um datagrama e guarda o endereço do
emissor
Envia um datagrama especificando o endereço
sendto
Comunicação entre processos
Sockets:
Aplicação cliente-servidor usando serviços de transporte orientado a conexão
servidor
cliente
criar porta para requisitante
Esperar pela requisição entrante
Criar porta – Conectar no servidor
Enviar requisição usando o socket criado
cria socket de comunicação
ler requisição do socket de conexão
Escrever resposta para o socket de conexão
Ler resposta do servidor
Fechar o socket
Fechar socket
Comunicação entre processos
Servidor
Sockets: orientado a conexão (tcp)
socket ()
bind ()
listen ()
accept ()
bloqueado
Cliente
socket ()
connect ()
write ()
read ()
write ()
close ()
read ()
close ()
Comunicação entre processos
Sockets: orientado a conexão (tcp) – estrutura típica do servidor
Comunicação entre processos
Sockets: Programação C/C++
C é a linguagem “básica” para programação
com sockets
De maneira diferente de Java, programar
com sockets em C/C++ envolve utilizar todas
as chamadas da API
Comunicação entre processos
#include ...
#include <sys/socket.h>
int main(int argc, char **argv)
{
int s;
struct sockaddr_in dest;
char msg_write[100], msg_read[100];
s = socket(AF_INET, SOCK_STREAM, 0));
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(9999);
inet_aton(“127.0.0.1”, &dest.sin_addr.s_addr);
connect(s, (struct sockaddr*)&dest, sizeof(dest));
do {
scanf("%s",msg_write);
write (s, msg_write, strlen(msg_write)+1);
read (s, msg_read, MAXBUF);
} while (strcmp(msg_read,"bye"));
close(s);
}
Comunicação entre processos
#include ...
#include <sys/socket.h>
int main(int argc, char **argv)
{
int s, client_s;
struct sockaddr_in self, client;
int addrlen = sizeof(client);
char msg_write[100], msg_read[100];
s = socket(AF_INET, SOCK_STREAM, 0);
bzero(&self, sizeof(self));
self.sin_family = AF_INET;
self.sin_port = htons(9999);
self.sin_addr.s_addr = INADDR_ANY;
bind(s, (struct sockaddr*)&self, sizeof(self));
listen(s, 5);
while (1) {
client_s = accept(s, (struct sockaddr*)&client, &addrlen);
do {
read (client_s, msg_read, MAXBUF);
write (client_s, msg_read, strlen(msg_read)+1);
} while (strcmp(msg_read,"bye"));
close(client_s);
}
}
Comunicação entre processos
Sockets: Programação Java
Java modernizou a API para trabalhar com sockets
O programador não precisa chamar todas as funções,
algumas chamadas são automáticas
Exemplos
Socket: equivalente a socket e bind
ServerSocket: equivalente a socket, bind e listen
Sockets são implementados no pacote java.net
A transmissão e o envio de dados são feitos através de
classes do pacote java.io de maneira semelhante à escrita e
leitura em arquivos
Classes DataInputStream, DataOutputStream, etc.,
Comunicação entre processos
Sockets:
Exemplo:cliente clienteJava (TCP) Java (TCP)
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String argv[]) throws
Exception
{
String sentence;
String modifiedSentence;
BufferedReader inFromUser =
new BufferedReader(new
InputStreamReader(System.in));
Socket clientSocket = new Socket("hostname", 6789);
DataOutputStream outToServer = new
DataOutputStream(clientSocket.getOutputStr
eam());
BufferedReader inFromServer =
new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()
));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println
("FROM SERVER: " + modifiedSentence
);
clientSocket.close();
}}
Comunicação entre processos
Exemplo:servidor servidor.Java (TCP) Java (TCP)
import java.io.*;
import java.net.*;
class TCPServer {
public static void main(String argv[]) throws
Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new
ServerSocket(6789);
while(true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new
InputStreamReader(connectionSocket.getInp
utStream()));
DataOutputStream outToClient =
new DataOutputStream
(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
capitalizedSentence =
clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
Comunicação entre processos
Sockets:
Aplicação cliente-servidor usando serviços de transporte não orientado a conexão
servidor
cliente
criar porta para requisitante
Criar porta (datagrama)
Enviar requisição para servidor
Especificando endereço do servidor e
número da porta
ler requisição do socket de conexão
Escrever resposta para o socket de conexão
Especificando endereço do cliente e número da porta
Ler resposta do servidor
Fechar socket
Comunicação entre processos
Servidor
Sockets: não orientado conexão (udp)
socket ()
bind ()
recvfrom ()
bloqueado
Cliente
socket ()
sendto ()
sendto ()
close ()
recvfrom ()
close ()
Comunicação entre processos
Cliente java UDP
import java.io.*;
import java.net.*;
class UDPClient {
public static void main(String args[]) throws
Exception
{
BufferedReader inFromUser =
new BufferedReader(new
InputStreamReader(System.in));
DatagramSocket clientSocket = new
DatagramSocket();
InetAddress IPAddress =
InetAddress.getByName("hostname");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData,
sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
DatagramPacket receivePacket =
new DatagramPacket(receiveData,
receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence =
new String(receivePacket.getData());
System.out.println("FROM SERVER:" +
modifiedSentence);
clientSocket.close();
}
}
Comunicação entre processos
Serrvidor java.udp
import java.io.*;
import java.net.*;
class UDPServer {
public static void main(String args[]) throws
Exception
{
DatagramSocket serverSocket = new
DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
DatagramPacket receivePacket =
new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
String sentence =
new String(receivePacket.getData());
InetAddress IPAddress =
receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalizedSentence =
sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData,
sendData.length, IPAddress,
port);
serverSocket.send(sendPacket);
}
}
}