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()
Beispiel #2
0
 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
Beispiel #3
0
    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.")