def send_fim(client): logging.info(f"Finished processing file",extra=LogHelper.set_extra('DATA',client.addr)) logging.info("Closing channel...",extra=LogHelper.set_extra('DATA',client.addr)) client.data_channel.close() logging.debug("Sending FIM",extra=LogHelper.set_extra('CONTROL',client.addr)) msg = MessageFactory.build("FIM") client.control_channel.send(msg)
def handle_client(client: ConnectingClient): logging.info("Connected to TCP channel",extra=LogHelper.set_extra('CONTROL',client.addr)) if not handle_hello(client): terminate_control_channel(client) return send_connection(client) if not handle_info_file(client): terminate_control_channel(client) return send_ok(client) if not handle_file(client): terminate_data_channel(client) terminate_control_channel(client) if not client.streamed_file.export_file(): logging.warning("Something went wrong while exporting file", extra=LogHelper.set_extra('DATA',client.addr)) terminate_data_channel(client) terminate_control_channel(client) send_fim(client) logging.info("Closing channel...",extra=LogHelper.set_extra('CONTROL',client.addr)) client.control_channel.close() return
def handle_hello(client): msg = client.control_channel.recv(comum.SIMPLE_MESSAGE_SIZE) decoded_message = MessageFactory.decode(msg) logging.debug(f"Received a {decoded_message.type}", extra=LogHelper.set_extra('CONTROL',client.addr)) if decoded_message.type != "HELLO": logging.warning("Client did not send HELLO",extra=LogHelper.set_extra("CONTROL", client.addr)) return False return True
def handle_ok(client): msg = client.recv(comum.SIMPLE_MESSAGE_SIZE) decoded_message = MessageFactory.decode(msg) if decoded_message.type != "OK": logging.warning(f"Server did not send OK",extra=LogHelper.set_extra('CONTROL',client.getpeername())) return False logging.debug(f"Received an OK to proceed sending the file",extra=LogHelper.set_extra('CONTROL',client.getpeername())) return True
def handle_info_file(client): msg = client.control_channel.recv(comum.INFO_FILE_MESSAGE_SIZE) decoded_message = MessageFactory.decode(msg) logging.debug(f"Received a {decoded_message.type}", extra=LogHelper.set_extra('CONTROL',client.addr)) if decoded_message.type != "INFO FILE": logging.warning("Client did not send a valid INFO FILE", extra=LogHelper.set_extra('CONTROL',client.addr)) return False client.create_streamed_file(decoded_message.file_name, decoded_message.file_size) logging.debug("Finished allocating structures for file", extra=LogHelper.set_extra('CONTROL',client.addr)) return True
def handle_file(client): logging.info("Started listening for file parts...",extra=LogHelper.set_extra('DATA',client.addr)) while not client.streamed_file.finished_streaming(): msg = client.data_channel.recvmsg(comum.FILE_MESSAGE_SIZE) decoded_message = MessageFactory.decode(msg[0]) if decoded_message.type == "FILE": threading.Thread(target = handle_file_part, args = (client, decoded_message)).start() else: logging.warning("Client did not send a valid FILE message",extra=LogHelper.set_extra('DATA',client.addr)) return False return True
def handle_connection_message(client): msg = client.recv(comum.CONNECTION_MESSAGE_SIZE) decoded_message = MessageFactory.decode(msg) if decoded_message.type != "CONNECTION": logging.warning("Server did not send a valid CONNECTION message",extra=LogHelper.set_extra('CONTROL',client.getpeername())) return None logging.debug(f"Received a CONNECTION message with port {decoded_message.udp_port}",extra=LogHelper.set_extra('CONTROL',client.getpeername())) return decoded_message.udp_port
def handle_fim(client): while True: msg = client.recv(comum.SIMPLE_MESSAGE_SIZE) decoded_message = MessageFactory.decode(msg) if decoded_message.type == "FIM": print(f"\n[{client.getpeername()[0]}:{client.getpeername()[1]} - CONTROL CHANNEL] Server finished processing file") return True elif decoded_message.type == "ACK": continue else: logging.warning("Server did not send neither a FIM or ACK message",extra=LogHelper.set_extra('CONTROL',client.getpeername())) return False
def send_file_part(file_control: FileControl, serial_number): payload = file_control.payloads[serial_number] message = MessageFactory.build("FILE",serial_number = serial_number, payload = payload, payload_size = len(payload)) #enquanto o pacote não tiver sido enviado corretamente while not file_control.sliding_window.get_transmitted(serial_number): logging.debug(f"Sending payload #{serial_number}",extra=LogHelper.set_extra('DATA',file_control.udp_addr)) file_control.data_channel.sendto(message, file_control.udp_addr) file_control.sliding_window.set_transmitted(serial_number,True) #essa thread dorme por TIMEOUT segundos time.sleep(TIMEOUT) #se depois de TIMEOUT segundos o arquivo ainda não foi acked pelo servidor, se mantém no loop if not file_control.sliding_window.get_acked(serial_number): logging.debug(f"Payload #{serial_number} wasn't acked, will resend",extra=LogHelper.set_extra('DATA',file_control.udp_addr)) file_control.sliding_window.set_transmitted(serial_number,False)
def send_info_file(client, file_name): try: file_size = os.path.getsize('./'+file_name) except: print(f"File {file_name} either doesn't exist or this program do not have access to it") return False try: message = MessageFactory.build("INFO FILE", file_name= file_name, file_size= file_size) except UnicodeEncodeError as err: print("Nome não permitido") if 'ascii' in err.args[0]: print("So podem caracteres da tabela ASCII") else: print(err.args[4]) return False logging.debug(f"Sending INFO FILE...",extra=LogHelper.set_extra('CONTROL',client.getpeername())) client.send(message) return True
def handle_ack(client: socket.socket, file_control: FileControl): acked_msgs = 0 progress_bar = None if logging.getLevelName(logging.root.level) != 'DEBUG': progress_bar = ProgressBar(len(file_control.payloads)) print('Upload progress:') progress_bar.init_print() while acked_msgs < len(file_control.payloads): msg = client.recv(comum.ACK_MESSAGE_SIZE) decoded_message = MessageFactory.decode(msg) if decoded_message.type != "ACK": logging.warning("Did not receive enough ACKs",extra=LogHelper.set_extra('CONTROL',client.getpeername())) return False if decoded_message.type == 'ACK': logging.debug(f"Received ACK for payload #{decoded_message.serial_number}",extra=LogHelper.set_extra('CONTROL',client.getpeername())) threading.Thread(target = file_control.sliding_window.acked, args=(decoded_message.serial_number,)).start() if progress_bar: progress_bar.increase() acked_msgs +=1 if progress_bar: progress_bar.end_print() return True
def terminate_data_channel(client): logging.warning("Terminating connection",extra=LogHelper.set_extra('DATA',client.addr)) client.data_channel.close()
def terminate_control_channel(client): logging.warning("Terminating connection",extra=LogHelper.set_extra('CONTROL',client.addr)) client.control_channel.close()
def send_ack(client: ConnectingClient, serial_number): logging.debug(f"Sending ACK to payload #{serial_number}...",extra=LogHelper.set_extra('DATA',client.addr)) message = MessageFactory.build('ACK', serial_number = serial_number) client.control_channel.send(message) client.streamed_file.sliding_window.acked(serial_number)
def handle_file_part(client, decoded_message): logging.debug(f"Received payload #{decoded_message.serial_number}...",extra=LogHelper.set_extra('DATA',client.addr)) client.streamed_file.set_payload(decoded_message.serial_number, decoded_message.payload) threading.Thread(target = send_ack, args = (client, decoded_message.serial_number)).start()
def send_hello(client:socket.socket): print(f"[{client.getpeername()[0]}:{client.getpeername()[1]} - CONTROL CHANNEL]Connected to TCP server") logging.debug("Sending HELLO...",extra=LogHelper.set_extra('CONTROL',client.getpeername())) message = MessageFactory.build("HELLO") client.send(message)
def terminate_data_channel(data_channel): logging.warning(f"Terminating connection",extra=LogHelper.set_extra('DATA',data_channel.getpeername())) data_channel.close()
def terminate_control_channel(client): logging.warning(f"Terminating connection",extra=LogHelper.set_extra('CONTROL',client.getpeername())) client.close()
def send_connection(client): udp_port = client.data_channel.getsockname()[1] msg = MessageFactory.build("CONNECTION",udp_port = udp_port) logging.debug(f"Sending CONNECTION message with port {udp_port}",extra=LogHelper.set_extra("CONTROL", client.addr)) client.control_channel.send(msg)
def send_ok(client): logging.debug("Sending OK", extra=LogHelper.set_extra('CONTROL',client.addr)) msg = MessageFactory.build("OK") client.control_channel.send(msg)