2. Exemplo de utilização de sockets sem ligação na comunicação entre 1 cliente e 2 servidores replicadosCopie o ficheiro aula7-dgram.tgz para a sua área de trabalho e descomprima o seu conteúdo:
tar xvfz aula7-dgram.zipa) Estude o código fonte e identifique a sequência de passos descritos no esquema;
b) Compile e execute o servidor. Localize o nome do socket do servidor;
c) Compile e execute o cliente. Compreenda o resultado. Verifique que o cliente também associa um nome ao seu socket.
Copie o ficheiro aula7-dgram2.tgz para a sua área de trabalho e descomprima o seu conteúdo:
tar xvfz aula7-dgram2.tgza) Estude o código fonte e identifique as diferênças em relação ao código do exercício anterior;
b) Compile e execute os servidores em 2 terminais distintos ( "./servidor 1" num terminal e "./servidor 2" noutro terminal);
c) Compile e execute o cliente num terceiro terminal. Verifique que o cliente recebe de volta a mensagem enviada aos dois servidores.
Nota: Os 2 servidores e o cliente podem ser executados no mesmo terminal. Por exemplo, ao executar-se na linha de comandos a sequência:
- ./server 1 &
- ./server 2 &
- ./client
Neste caso, os 2 servidores são executados em background (o caracter &) e o cliente em foreground.
1. Comunicação Cliente-Servidor SNFS
O suporte à replicação de servidores SNFS para melhorar o desempenho é um dos objectivos do projecto. A figura que segue, mostra a arquitectura do sistema cliente-servidor SNFS sem replicação de servidor.
O mecanismo de comunicação cliente-servidor SNFS utiliza sockets Unix sem ligação (datagram). Os componentes envolvidos na comunicação são: snfs_api.c, snfs.c e server.c, e as interfaces snfs_api.h, snfs_proto.h e snfs.h. O servidor fornecido implementa os serviços SNFS (snfs.c) indicados no enunciado. Do lado do cliente, já se encontram implementadas as interfaces API SNFS (snfs_api.c e myfs.c) que permitem aos clientes invocar os serviços a um servidor apenas (snfs_api.h contém a assinatura de todas as funções da API). A interface snfs_proto.h é comum a clientes/servidor e descreve o formato das mensagens trocadas.
Neste exercício, pretende-se implementar a comunicação entre um cliente e N servidores replicados efectuando algumas alterações no código dos ficheiros snfs_api.c, myfs.c e server.c. Mais especificamente, pretende-se que que um cliente ao enviar um pedido a N servidores, esse pedido tem sucesso se o cliente receber a resposta de cada um dos N servidores.
Procedimento
Para compreender a comunicação entre o cliente e o servidor SNFS, deverá ser estudada a parte do código do cliente que efectua a comunicação com o servidor e a parte do código do servidor que inicializa e mantem a comunicação com os clientes.
a) Copie o pacote sthreads+snfs+test-skel2.v2.tgz, descomprima-o e instale-o na sua área de trabalho. Identifique os componentes da arquitectura;
b) Considere o código do servidor SNFS server.c no directório snfs_server:
- Modifique o nome atribuído aos sockets dos servidores para suportar a nomenclatura "server_0, server_1, .., server_N";
- Observe, no ciclo principal do servidor, como é efectuada a inicialização do socket datagram que permite receber e enviar pedidos aos clientes;
- Modifique esse código para suportar o modo multi-servidor:
- Em concreto cada servidor deverá ser lançado com 2 argumentos: um relativo ao tempo de acesso aos blocos do sistema de ficheiros e outro como identificador do servidor réplica (Por exemplo, se N=3, ter-se-á que executar ./server 200000 1 , ./server 250000 2 , ./server 200000 3 . Os valores 200000 e 250000 são o tempo de acesso aos blocos do sistema de ficheiros dos servidores 1 e 3, e 250000 é o tempo de acesso aos blocos do sistema de ficheiros do servidor 2.
c) Após as alterações compile o servidor (make) e corra o executável em terminais distintos (podem ser executados no mesmo terminal, como visto no exercício anterior), digitando na linha de comandos de cada um ./server 800000 1 , server 300000 2, ..,(os valores do tempo de acesso ao sistema de ficheiros aqui indicados, são apenas para exemplificar). Verifique que foram criados N sockets;
d) Considere o código do cliente SNFS (directório snfs_lib):
- Modifique o código do cliente para enviar os pedidos aos múltiplos servidores. Em particular, altere:
- A função static int remote_call(snfs_msg_req_t *req, int reqsz, snfs_msg_res_t *res, int ressz, int to_all_servers), reponsável pelo envio e recepção de pedidos;
- A função int snfs_init(char* cli_name, char* server_name) que inicializa os sockets datagram de comunicação.
e) Altere o código dos ficheiros mysf.c e mysf.h para que a chamada à função de inicialização do cliente snfs_init() tenha em conta a comunicação com N servidores;
f) Após as alterações recompile o pacote para que a livraria cliente SNFS fique disponível;
g) Para testar as alterações introduzidas:
- No directório test-snfs-replica existem 20 exemplos de aplicações (cliente) de teste que usam directamente a biblioteca API SNFS para a comunicação entre um cliente e N servidores;
- Pôr em execução os N=4 servidores replicados;
- Após a compilação, execute os testes um de cada vez (convém reeniciar os servidores todas as vezes que se usa um teste para que o mesmo tenha sucesso).
2. Utilização de sockets com ligação - stream
Copie o ficheiro aula7-stream.tgz para a sua área de trabalho e descomprima o seu conteúdo:
tar xvfz aula7-stream.tgza) Estude o código fonte e identifique a sequência de passos de acordo com o esquema;
b) Compile e execute o servidor e o cliente. Compare o resultado com o obtido na introdução 1.
Exercício Suplementar
Select
Implemente um servidor com a funcionalidade observada nos pontos 1 da Introdução e no exercício 2. Este servidor deve ter a possibilidade de interagir com clientes do tipo stream e datagram.
Será necessário investigar o funcionamento da chamada sistema select e utilizar as primitivas respectivas:
select
,FD_SET
,FD_CLR
,FD_ISSET
eFD_ZERO
. Recomenda-se a consulta do exemplo aula7-select.tgz.