def serve_client(self, client, address): total_time = datetime.now() pkt = self.wait_for_request(client, address) if not pkt: return 1 file = SERVER_FOLDER + pkt.__get__('file') if os.path.isfile(file): # if file is found on the server pkt = Packet(status='found') client.send(pkt.__dump__()) # Logic goes here f = open(file=file, mode='rb') data = f.read() bits = len(data) * 8 # Build packet packets = [ Packet(data=data[i: i + CHUNK_SIZE], seq_num=i // CHUNK_SIZE) for i in range(0, len(data), CHUNK_SIZE) ] timeout_count = self.begin_transimission( packets=packets, client=client, address=address) total_time = (datetime.now() - total_time).total_seconds() print('Sent ' + str(bits) + ' bits, in ' + str(total_time) + ' secs, with ' + str(timeout_count) + ' timeouts') with open('GBNlog.txt', 'a') as log: run_metrics = DELIMITER.decode() + '\n' run_metrics += 'TYPE=GBN\n' run_metrics += 'THROUGHPUT=' + \ str(bits / total_time) + '\n' run_metrics += 'PACKET_LOSS=' + \ str(LOSS_PROBABILITY) + '\n' log.write(run_metrics) else: # if file not found, send not found packet pkt = Packet(status='not_found') client.send(pkt.__dump__()) print('Client disconnected, address: ', address) client.close()
def begin_transimission(self, packets, client, address): base = 0 self.send_window(packets, base, client, address) client_timeout_count = CLIENT_TIMEOUT_TRIALS while client_timeout_count: if base >= len(packets): break end = base + WINDOW_SIZE end = end if end < len(packets) else len(packets) client.settimeout(TIME_OUT_SEC) try: # Wait for response or timeout res = client.recv(PACKET_SIZE) if not res: break pkt = Packet(res=res) pkt.__print__(from_address=address) seq_num = int(pkt.__get__('seq_num')) if base <= seq_num <= base + WINDOW_SIZE: if pkt.__get__('ack') == '+': client.settimeout(None) free_slots = int(pkt.__get__('seq_num')) - base + 1 nEnd = end + free_slots nEnd = nEnd if nEnd < len(packets) else len(packets) new_pkts = packets[end:nEnd] for pkt in new_pkts: if randint(1, 100) > LOSS_PROBABILITY: pkt.__print__(to_address=address) client.send(pkt.__dump__()) else: print(colored('Simulating Packet Loss: ' + pkt.__get__('seq_num'), 'red')) base += free_slots else: print(colored('Ack out of window, discard ' + str(seq_num) + ' => from: ' + str(address), color='blue')) except timeout: print(colored('Timeout, resending window. => to: ' + str(address), color='red')) self.send_window(packets, base, client, address) client_timeout_count -= 1 # Retrun number of timeouts return CLIENT_TIMEOUT_TRIALS - client_timeout_count