def check_connection(self): try: self.create_socket("AF_INET", "SOCK_DGRAM") self.__s.setblocking(False) self.__s.settimeout(10) test_packet = SWPacket(4, 0, 4, packet_type=PacketType.CHECK) self.__s.sendto(test_packet.get_data(), (self.__receiver_ip, self.__receiver_port)) data_readed, address = self.__s.recvfrom(4) if data_readed != None and int.from_bytes( data_readed[:1], "big") == PacketType.CHECK: self.log_message_signal.emit("Conexiunea este valida!") else: self.log_message_signal.emit("Conexiunea este invalida!") except ConnectionResetError: self.log_message_signal.emit("Eroare! Conexiunea este invalida!") except Exception as e: self.log_message_signal.emit("check_connection: " + str(e)) finally: self.__s.close()
def pack_data(self): new_packet = SWPacket(self.__packet_size_in_bytes, self.__data_size_in_bytes, self.__header_size_in_bytes, packet_type=PacketType.DATA) new_packet.set_packet_number(self.__packet_number) self.__packet_number += 1 new_packet.store_data(self.__file_reader.read()) return new_packet
def get_end_file_packet(self): end_packet = SWPacket(self.__packet_size_in_bytes, self.__data_size_in_bytes, self.__header_size_in_bytes, packet_type=PacketType.DATA) end_packet.make_end_packet() end_packet.set_packet_number(self.__packet_number) return end_packet
def forceCloseReceiver(self): data_packet = SWPacket(self.receiver.DATA_PACKET_SIZE, self.receiver.DATA_SIZE, self.receiver.PACKET_HEADER_SIZE, packet_type=PacketType.DATA) data_packet.make_end_packet() data_packet.set_packet_number(0xFFFFFF) try: if self.receiver.is_socket_open() == True: self.receiver.get_socket().sendto(data_packet.get_data(), (self.receiver.get_ip_address(), self.receiver.get_port())) except PermissionError as pe: self.write_in_log("[" + str(datetime.now().time()) + "] " + "Nu aveti permisiunea de a trimite pachete la adresa la care ati facut bind.") except OSError as os: self.write_in_log("[" + str(datetime.now().time()) + "] " + "Nu puteti timite pachete cu socket-ul inchis.")
def close_sender(self): try: if self.__sender_run_flag == True: data_packet = SWPacket(self.__packet_size, self.__packet_data_size, self.__packet_header_size, packet_type=PacketType.DATA) data_packet.make_end_packet() data_packet.set_packet_number(0xFFFFFF) self.__s.sendto(data_packet.get_data(), (self.__receiver_ip, self.__receiver_port)) self.__sender_run_flag = False except Exception as e: self.log_message_signal.emit(str(e)) finally: self.__s.close()
def start_receiver(self): if self.__error_occurred == True: # Daca s-a intamplat vreo eroare la crearea socket-ului, procedura de gestionare a pachetelor nu mai are loc. self.__error_occurred = False return data_packet = SWPacket(self.DATA_PACKET_SIZE, self.DATA_SIZE, self.PACKET_HEADER_SIZE, packet_type=PacketType.INIT) ack_packet = SWPacket(self.ACK_PACKET_SIZE, 0, self.PACKET_HEADER_SIZE, packet_type=PacketType.ACK) name = "new_" self.log_signal.emit("Probabilitatea de pierdere a pachetelor este: " + str(self.__losing_packets_probability)) self.log_signal.emit("Se asteapta pachete...") ########################### Incepere gestionare pachete ############################### while self.__is_running: try: data_readed, address = self.__s.recvfrom( self.DATA_PACKET_SIZE) # Primire pachete except socket.timeout: self.log_signal.emit("Timeout-ul de " + str(socket.getdefaulttimeout()) + " secunde al receiver-ului s-a terminat.") self.__is_running = False continue except OSError as os: if "[WinError 10040]" in str(os): self.log_signal.emit( "[WinError 10040] S-a primit un pachet mai mare decat dimensiunea buffer-ului de receptie." ) self.log_signal.emit( "Se asteapta pachete in continuare...") continue self.__nr_of_packets_recv += 1 ########################### Testarea conexiunii ############################### if int.from_bytes( data_readed[:self.PACKET_HEADER_SIZE - self.PACKET_COUNTER_SIZE], "big" ) == PacketType.CHECK: # Retrimitere pachete de conexiune self.log_signal.emit( "Am primit mesaj de testare a conexiunii de la adresa: " + str(address)) self.__s.sendto(data_readed, address) continue ########################### Aruncare pachete ############################### data_packet.create_packet(data_readed) type, nr_packet, data = self.__ups.unpack(data_packet) if is_packet_lost(self.__losing_packets_probability) or ( self.__last_packet_received == -1 and nr_packet != self.FIRST_PACKET and nr_packet != 0xFFFFFF ): # Verificam daca vom pierde intentionat acest pachet self.log_signal.emit("Am aruncat pachetul cu numarul: " + str(nr_packet)) self.__nr_of_packets_lost += 1 continue ########################### Trimitere ACK ############################### self.log_signal.emit("Am primit pachetul cu numarul: " + str(nr_packet)) ack_packet.set_packet_number( nr_packet) # Trimitem ACK pentru fiecare pachet primit self.__s.sendto(ack_packet.get_header(), address) ########################### Mecanism sliding window ############################### if nr_packet == self.__last_packet_received + 1: # Gestionarea pachetului urmator if type == PacketType.DATA: if self.__file_writer.is_open() == True: self.__file_writer.write_in_file(data) else: self.log_signal.emit( "S-a incercat scrierea intr-un fisier inchis.") elif type == PacketType.INIT: if nr_packet == self.FIRST_PACKET: start = time.time() self.__total_nr_of_packets_to_receive = int.from_bytes( self.__ups.get_byte_x_to_y(1, 3, data), "big") self.set_total_nr_of_packets_signal.emit( self.__total_nr_of_packets_to_receive) self.DATA_PACKET_SIZE = int.from_bytes( self.__ups.get_byte_x_to_y(4, 5, data), "big") self.DATA_SIZE = self.DATA_PACKET_SIZE - self.PACKET_HEADER_SIZE data_packet = SWPacket(self.DATA_PACKET_SIZE, self.DATA_SIZE, self.PACKET_HEADER_SIZE, packet_type=PacketType.DATA) self.log_signal.emit( "Se vor primii " + str(self.__total_nr_of_packets_to_receive) + " pachete a cate " + str(self.DATA_PACKET_SIZE) + " octeti fiecare.") self.__ups.set_packet_size(self.DATA_PACKET_SIZE) self.__SWR_size = int.from_bytes( self.__ups.get_byte_x_to_y(6, 6, data), "big") self.log_signal.emit("Dimensiunea ferestrei este: " + str(self.__SWR_size)) name += self.__ups.get_byte_x_to_y( 7, self.DATA_SIZE, data).decode("ascii") self.__file_writer.set_file_name(name) self.__file_writer.open_file() self.log_signal.emit( "Am deschis fisierul cu numele: " + name) else: self.__last_packet_received += 1 self.log_signal.emit("Ultimul pachet a fost: " + str(self.__last_packet_received)) self.loading_bar_signal.emit(nr_packet + 1) break self.__last_packet_received += 1 while self.__last_packet_received + 1 in self.__SWR.keys( ): # Gestionarea pachetului care ocupa primul loc din fereastra (type, data) = self.__SWR[self.__last_packet_received + 1] self.__SWR.pop(self.__last_packet_received + 1) if type == PacketType.DATA: if self.__file_writer.is_open() == True: self.__file_writer.write_in_file(data) else: self.log_signal.emit( "S-a incercat scrierea intr-un fisier inchis.") else: self.__last_packet_received += 1 self.__is_running = False self.log_signal.emit("Ultimul pachet a fost: " + str(self.__last_packet_received)) break self.__last_packet_received += 1 elif nr_packet > self.__last_packet_received + 1: # Gestionarea pachetului primit care nu ar ocupa primul loc din fereastra if nr_packet == 0xFFFFFF: self.__is_running = False continue self.__SWR[nr_packet] = (type, data) if len(self.__SWR) > self.__SWR_size: self.log_signal.emit( "Eroare! S-a depasit dimensiunea ferestrei. Se opreste receptia pachetelor." ) self.__is_running = False continue self.loading_bar_signal.emit(self.__last_packet_received + 1) # Update loading bar ########################### Terminare executie receiver ############################### if self.__total_nr_of_packets_to_receive == self.__last_packet_received + 1: end = time.time() self.log_signal.emit("Done!") self.log_signal.emit("Timp de executie: " + str(end - start)) self.log_signal.emit("Procentul de pachete pierdute este: " + str(100 * float("{:.4f}".format( float(self.__nr_of_packets_lost / self.__nr_of_packets_recv), 2))) + "%") else: self.log_signal.emit( "Program inchis de utilizator sau sender-ul s-a oprit.") if self.__file_writer.is_open(): # Inchidem fisier self.__file_writer.close_file() self.log_signal.emit("Fisierul s-a inchis.") while self.__total_nr_of_packets_to_receive == self.__last_packet_received + 1: # Trimitem ACK-uri pierdute self.log_signal.emit( "Se asteapta pachete pentru care s-a pierdut confirmarea.") self.log_signal.emit("Receiver-ul se opreste automat in " + str(socket.getdefaulttimeout()) + " secunde daca nu se primesc pachete.") try: data_readed, address = self.__s.recvfrom(self.DATA_PACKET_SIZE) except socket.timeout: self.log_signal.emit( "Timeout-ul de " + str(socket.getdefaulttimeout()) + " secunde al receiver-ului in partea de ACK s-a terminat.") break data_packet.create_packet(data_readed) type, nr_packet, data = self.__ups.unpack(data_packet) if nr_packet == 0xFFFFFF: self.log_signal.emit("Program finalizat cu succes.") break elif nr_packet > self.__last_packet_received - self.__SWR_size: # Verificam ca pachete primite sa ocupe ultima fereastra self.log_signal.emit( "Am primit ACK pentru pachetul cu numarul: " + str(nr_packet)) ack_packet.set_packet_number(nr_packet) self.__s.sendto(ack_packet.get_header(), address) self.close_connection() self.finish_signal.emit() # Resetam butoanele interfetei self.reset_receiver()
def send_packages_to_buffer(self): try: self.log_message_signal.emit("Se trimite fisierul " + self.__path.split("/")[-1]) count = 0 self.__ps.reset() self.__ps.open_file(self.__path) if self.__ps.get_file_size() < (2**24 - 2) * self.__packet_size: first_packet = SWPacket(self.__packet_size, self.__packet_data_size, self.__packet_header_size, packet_type=PacketType.INIT) file_name = self.__path.split("/")[-1] if len(file_name) > self.__MAX_FILE_NAME_SIZE: file_name = file_name[0:self.__MAX_FILE_NAME_SIZE - len(file_name.split(".")[-1]) - 1] + "." + file_name.split(".")[-1] print(file_name) first_packet.store_data(bytes(file_name, 'utf-8')) packets_to_send = 0 if self.__ps.get_file_size( ) % self.__ps.get_data_size_in_bytes() != 0: packets_to_send = int( self.__ps.get_file_size() / self.__ps.get_data_size_in_bytes()) + 3 else: packets_to_send = int( self.__ps.get_file_size() / self.__ps.get_data_size_in_bytes()) + 2 first_packet.set_packets_to_send(packets_to_send) first_packet.set_window_size(self.__window_size) count += 1 first_packet.set_packet_size(self.__packet_size) self.__buffer.put(first_packet) self.__thread_1 = threading.Thread(target=self.wait_for_ACK) self.__thread_2 = threading.Thread( target=self.send_files_with_SW) self.__thread_1.start() self.__thread_2.start() print(binascii.hexlify(first_packet.get_data())) for i in range( int(self.__ps.get_file_size() / self.__ps.get_data_size_in_bytes()) + 1): if self.__sender_run_flag == False: self.__ps.close_file() self.log_message_signal.emit( "S-a terminat thread-ul care pune pachete in buffer mai devreme din cauza unei erori." ) self.__thread_1.join() self.__thread_2.join() return self.__condition.acquire() if self.__buffer.qsize() == self.__QUEUE_SIZE: self.__condition.wait(3) if self.__sender_run_flag == False: self.__condition.notify() self.__condition.release() continue self.__buffer.put(self.__ps.pack_data()) self.__condition.notify() self.__condition.release() count += 1 time.sleep(0.001) self.__buffer.put(self.__ps.get_end_file_packet()) count += 1 self.log_message_signal.emit( "Numarul teoretic de pachete generate: " + str( int(self.__ps.get_file_size() / self.__ps.get_data_size_in_bytes()) + 3)) self.log_message_signal.emit( "Numarul de pachete puse in buffer este: " + str(count)) self.__ps.close_file() self.log_message_signal.emit( "S-a terminat thread-ul care pune pachete un buffer.") self.__thread_1.join() self.__thread_2.join() else: self.log_message_signal.emit( "Fisierul este prea mare pentru a putea fi trimis!") self.log_message_signal.emit( "Va rugam mariti dimensiunea campului de date din pachet daca se poate." ) except Exception as e: self.__sender_run_flag = False self.log_message_signal.emit( "send_packages_to_buffer: Conexiunea s-a inchis dintr-o cauza necunoscuta." ) self.log_message_signal.emit("send_packages_to_buffer: " + str(e)) return
def wait_for_ACK(self): try: self.log_message_signal.emit( "S-a pornit thread-ul care asteapta mesaje de ACK") packet = SWPacket(4, 0, 4, packet_type=PacketType.ACK) last_packet_acknowledged = False self.__s.setblocking(False) self.__s.settimeout(10) while 1: data_readed, address = self.__s.recvfrom(5) packet.create_packet(data_readed) package_type, nr_packet, data = self.__ups.unpack(packet) if package_type == PacketType.ACK and nr_packet >= self.__lowest_window_package: self.__mutex.acquire() try: self.__recent_packets_sent.pop(nr_packet) except KeyError: continue finally: self.__mutex.release() self.__packages_sent_and_received += 1 self.log_message_signal.emit( "Am primit raspuns pozitiv pentru " + str(nr_packet)) if nr_packet == int( self.__ps.get_file_size() / self.__ps.get_data_size_in_bytes() ) + 2 or last_packet_acknowledged == True: last_packet_acknowledged = True if bool(self.__recent_packets_sent) == False: break if nr_packet == self.__lowest_window_package: for i in range( self.__lowest_window_package + 1, self.__lowest_window_package + self.__window_size + 1): if i not in self.__recent_ACK_received: for k in range( self.__lowest_window_package + 1, i): self.__recent_ACK_received.pop(k) self.__lowest_window_package = i break else: self.__recent_ACK_received[nr_packet] = nr_packet if self.__sender_run_flag == False: self.log_message_signal.emit( "wait_for_ack: Conexiunea s-a inchis dintr-o cauza necunoscuta." ) return #self.log_message_signal.emit("slowest: " + str(self.__lowest_window_package)) except Exception as e: self.log_message_signal.emit( "wait_for_ack: Conexiunea s-a inchis dintr-o cauza necunoscuta." ) self.log_message_signal.emit("wait_for_ACK: " + str(e)) self.__sender_run_flag = False return self.log_message_signal.emit( "S-a terminat thread-ul care asteapta mesaje de ACK.")