''' ------------------------------------ HEADER ------------------------------------ Autores: Michel Brasil Cordeiro (GRR20172663) Vinícius Teixeira Vieira dos Santos (GRR20186716) Descrição: Arquivo contendo a implementação de um servidor com uma tabela cache seguindo as especificações do trabalho prático da discipliba Redes De Computadores II. Requisitos de uso: Para que o servidor cache funcione corretamente, é necessário que os três servidores de temperatura tenham sido inicializados no modo de escuta. Última atualização: 22/04/2022 -------------------------------------------------------------------------------- ''' import socket import time from lib import * print("Iniciando servidor com a tabela cache.") #Inicializando tabela cache '''A tabela cache é um dicionário possui o id do servidor como sendo a chave e um e uma lista com a horário da gravação e a temperatura''' cache = {0:[0.0,0],1:[0.0,0],2:[0.0,0]} #Conectando-se com os servidores print("Conectando-se com o primeiro servidor...") server0_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) while True: try: server0_sock.connect((HOST_SERVER_0, PORT_SERVER_0)) break except socket.error as e: print(f"Erro ao conectar com o servidor 0: {e}") input("Aperte enter para tentar de novo.") print("Conectado") print("Conectando-se com o segundo servidor...") server1_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) while True: try: server1_sock.connect((HOST_SERVER_1, PORT_SERVER_1)) break except socket.error as e: print(f"Erro ao conectar com o servidor 1: {e}") input("Aperte enter para tentar de novo.") print("Conectado") print("Conectando-se com o terceiro servidor...") server2_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) while True: try: server2_sock.connect((HOST_SERVER_2, PORT_SERVER_2)) break except socket.error as e: print(f"Erro ao conectar com o servidor 2: {e}") input("Aperte enter para tentar de novo.") print("Conectado") #Conectando-se com o cliente print("Esperando conexão com o cliente...") c_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) c_sock.bind((HOST_CACHE, PORT_CACHE)) c_sock.listen() client, addr = c_sock.accept() print("Conectado com o cliente.") with client: while True: print("Esperando requisição.") data = client.recv(12) m = bytes_to_message(data) print("Chegou requisição.") #Se a mensagem contém uma requisição de temperatura if m.message_type == MSG_REQ: line = cache[m.server_id] #verifica se a entrada da tabela ainda é válida if line[0] > (time.time() - TIMEOUT): print("Informação da tabela é válida.\nRespondendo o cliente.") answer = Message(0,MSG_RESP,line[1]) client.sendall(answer.message_to_bytes()) # entrada não é válida else: #enviando a requisição e recebendo a resposta if m.server_id == 0: server0_sock.sendall(m.message_to_bytes()) data = server0_sock.recv(12) elif m.server_id == 1: server1_sock.sendall(m.message_to_bytes()) data = server1_sock.recv(12) else: server2_sock.sendall(m.message_to_bytes()) data = server2_sock.recv(12) answer = bytes_to_message(data) print("Chegou resposta.") if answer.message_type == MSG_ERR: print("Ocorreu um erro ao obter a temperatura.") else: print("Atualizando a tabela cache.") line = [time.time(), answer.data] cache[m.server_id] = line print("Respondendo o cliente.") client.sendall(answer.message_to_bytes()) #Se a mensagem contém uma requisição de encerramento elif m.message_type == MSG_END: print("Chegou requisição de ecerramento.") print("Encerrando servidores.") #Encaminha a mensagem para todos os servidores m.server_id = 0 server0_sock.sendall(m.message_to_bytes()) m.server_id = 1 server1_sock.sendall(m.message_to_bytes()) m.server_id = 2 server2_sock.sendall(m.message_to_bytes()) #Sai do while break else: print("Erro: Tipo da mensagem inválido") #Fim do while #Fim do with print("Fechando sockets.") server0_sock.close() server1_sock.close() server2_sock.close() c_sock.close() print("Fim")