Exemple #1
0
    def handle_arrival_msg(self):
        msg = self.network_layer.recv()
        msg_data = util.extract_data(msg)

        if (msg_data.is_corrupt):
            if (self.is_receiver):
                if self.expected_sequence_number == 0:
                    util.log("Packet received is corrupted. " +
                             self.NO_PREV_ACK_MSG)
                    return
                self.network_layer.send(self.receiver_last_ack)
                util.log("Received corrupted data. Resending ACK: " +
                         util.pkt_to_string(
                             util.extract_data(self.receiver_last_ack)))
            return

        # Si es un mensaje ACK message, se asume que es para el emisor.
        if msg_data.msg_type == config.MSG_TYPE_ACK:
            self.sender_lock.acquire()
            self.sender_base = msg_data.seq_num + 1
            if (self.sender_base == self.next_sequence_number):
                util.log(
                    "Received ACK with seq # matching the end of the window: "
                    + util.pkt_to_string(msg_data) + ". Cancelling timer.")
                self.timer.cancel()
            else:
                util.log(
                    "Received ACK: " + util.pkt_to_string(msg_data) +
                    ". There are messages in-flight. Restarting the timer.")
                if self.timer.is_alive(): self.timer.cancel()
                self.set_timer()
                self.timer.start()
            self.sender_lock.release()
        # Si es un mensaje DATA,se asume que es para el receptor
        else:
            assert msg_data.msg_type == config.MSG_TYPE_DATA
            util.log("Received DATA: " + util.pkt_to_string(msg_data))
            if msg_data.seq_num == self.expected_sequence_number:
                self.msg_handler(msg_data.payload)
                ack_pkt = util.make_packet(b'', config.MSG_TYPE_ACK,
                                           self.expected_sequence_number)
                self.network_layer.send(ack_pkt)
                self.receiver_last_ack = ack_pkt
                self.expected_sequence_number += 1
                util.log("Sent ACK: " +
                         util.pkt_to_string(util.extract_data(ack_pkt)))
            else:
                if self.expected_sequence_number == 0:
                    util.log("Packet received is out of order. " +
                             self.NO_PREV_ACK_MSG)
                    return
                util.log("DATA message had unexpected sequence #" +
                         str(int(msg_data.seq_num)) +
                         ". Resending ACK message with sequence # " +
                         str(int(self.expected_sequence_number - 1)) + ".")
                self.network_layer.send(self.receiver_last_ack)
        return
Exemple #2
0
    def handle_arrival_msg(self):
        NO_PREV_ACK_MSG = "Don't have previous ACK to send, will wait for server to timeout."
        msg = self.network_layer.recv()
        msg_data = util.extract_data(msg)

        # Ignore corrupt, let it lapse into timeout, no time to do hahahahahaha
        # if msg_data.is_corrupt:
        #     if self.is_receiver:
        #         if self.expected_sequence_number == 0:
        #             util.log("Packet received is corrupted. " + NO_PREV_ACK_MSG)
        #             return
        #         self.network_layer.send(self.receiver_last_ack)
        #         util.log("Received corrupted data. Resending ACK: "
        #                  + util.pkt_to_string(util.extract_data(self.receiver_last_ack)))
        #     return

        # If ACK message, assume its for sender
        if msg_data.msg_type == config.MSG_TYPE_ACK:
            self.sender_lock.acquire()
            util.log("Received ACK: " + util.pkt_to_string(msg_data) +
                     ". Mark as acked")
            self.windows[msg_data.seq_num].acked = True
            self.windows.pop(msg_data.seq_num, None)
            if self.sender_base == msg_data.seq_num:
                self.sender_base = min(self.windows.keys())
            self.sender_lock.release()
        # If DATA message, assume its for receiver
        else:
            assert msg_data.msg_type == config.MSG_TYPE_DATA
            util.log("Received DATA: " + util.pkt_to_string(msg_data))
            # can receive messages out of order
            # if msg_data.seq_num == self.expected_sequence_number:
            #     self.msg_handler(msg_data.payload)
            #     ack_pkt = util.make_packet(b'', config.MSG_TYPE_ACK, self.expected_sequence_number)
            #     self.network_layer.send(ack_pkt)
            #     self.receiver_last_ack = ack_pkt
            #     self.expected_sequence_number += 1
            #     util.log("Sent ACK: " + util.pkt_to_string(util.extract_data(ack_pkt)))
            # else:
            #     if self.expected_sequence_number == 0:
            #         util.log("Packet received is out of order. " + NO_PREV_ACK_MSG)
            #         return
            #     util.log("DATA message had unexpected sequence #"
            #              + str(int(msg_data.seq_num)) + ". Resending ACK message with sequence # "
            #              + str(int(self.expected_sequence_number - 1)) + ".")
            #     self.network_layer.send(self.receiver_last_ack)
        return
Exemple #3
0
 def _timeout(self):
     util.log("Timeout! Resend last packet: " +
              util.pkt_to_string(self.last_pkt_sent_data))
     self.sender_lock.acquire()
     self.network_layer.send(self.last_pkt_sent)
     self.set_timer()
     self.sender_lock.release()
     self.timer.start()
     return
Exemple #4
0
    def handle_arrival_msg(self):
        msg = self.network_layer.recv()
        msg_data = util.extract_data(msg)

        if (msg_data.is_corrupt):
            if (self.is_receiver):
                if not self.last_pkt_sent_data: return
                util.log("Received corrupt data. Resending: " +
                         util.pkt_to_string(self.last_pkt_sent_data))
                self.network_layer.send(self.last_pkt_sent)
            return

        # If ACK message, assume its for sender
        if msg_data.msg_type == config.MSG_TYPE_ACK:
            if self.sender_state == config.WAIT_FOR_ACK_MSG and msg_data.seq_num == self.sequence_number:
                util.log("Received ACK with expected seq #. " +
                         util.pkt_to_string(msg_data))
                self.sender_lock.acquire()
                self.timer.cancel()
                self.sequence_number = not (self.sequence_number
                                            )  # flip the sequence number
                self.sender_state = config.WAIT_FOR_APP_DATA
                self.sender_lock.release()
        # If DATA message, assume its for receiver
        else:
            assert msg_data.msg_type == config.MSG_TYPE_DATA
            util.log("Received DATA: " + util.pkt_to_string(msg_data))
            if msg_data.seq_num == self.sequence_number:
                self.msg_handler(msg_data.payload)
                ack_pkt = util.make_packet(b'', config.MSG_TYPE_ACK,
                                           self.sequence_number)
                self.network_layer.send(ack_pkt)
                self.last_pkt_sent = ack_pkt
                self.last_pkt_sent_data = util.extract_data(ack_pkt)
                self.sequence_number = not (self.sequence_number
                                            )  # flip the sequence number
                util.log("Sent ACK: " +
                         util.pkt_to_string(self.last_pkt_sent_data))
            else:
                util.log(
                    "Duplicate DATA message. Resending ACK message with sequence # "
                    + str(int(self.last_pkt_sent_data.seq_num)) + ".")
                self.network_layer.send(self.last_pkt_sent)
        return
Exemple #5
0
 def _send_helper(self, msg):
     self.sender_lock.acquire()
     packet = util.make_packet(msg, config.MSG_TYPE_DATA,
                               self.next_sequence_number)
     packet_data = util.extract_data(packet)
     self.window[self.next_sequence_number % config.WINDOW_SIZE] = packet
     util.log("Sending data: " + util.pkt_to_string(packet_data))
     w = SingleWindow(self.next_sequence_number, self.network_layer, packet,
                      self.sender_lock).start()
     self.windows[self.next_sequence_number] = w
     self.next_sequence_number += 1
     self.sender_lock.release()
     return
Exemple #6
0
 def _timeout(self, seq_num):
     util.log(f"Timeout! Resending packet {seq_num}")
     self.sender_lock.acquire()
     packet_offset_index = (seq_num - self.sender_base) % config.WINDOW_SIZE
     self.timer_list[packet_offset_index].cancel()
     self.timer_list[packet_offset_index] = self.set_timer(seq_num)
     pkt = self.sender_buffer[packet_offset_index]
     self.network_layer.send(pkt)
     util.log("Resending packet: " +
              util.pkt_to_string(util.extract_data(pkt)))
     self.timer_list[packet_offset_index].start()
     self.sender_lock.release()
     return
Exemple #7
0
 def _timeout(self):
   util.log("Timeout! Resending all packets in window. Resending packets with seq #s "
            + str(self.sender_base) + "-" + str(self.next_sequence_number-1) +".")
   self.sender_lock.acquire()
   if self.timer.is_alive(): self.timer.cancel()
   self.set_timer()
   for i in range(self.sender_base,self.next_sequence_number):
     pkt = self.window[(i%config.WINDOW_SIZE)]
     self.network_layer.send(pkt)
     util.log("Resending packet: " + util.pkt_to_string(util.extract_data(pkt)))
   self.timer.start()
   self.sender_lock.release()
   return
Exemple #8
0
 def _send_helper(self, msg):
   self.sender_lock.acquire()
   packet = util.make_packet(msg, config.MSG_TYPE_DATA, self.next_sequence_number)
   packet_data = util.extract_data(packet)
   self.window[self.next_sequence_number%config.WINDOW_SIZE] = packet
   util.log("Sending data: " + util.pkt_to_string(packet_data))
   self.network_layer.send(packet)
   if self.sender_base == self.next_sequence_number:
     if self.timer.is_alive(): self.timer.cancel()
     self.set_timer()
     self.timer.start()
   self.next_sequence_number += 1
   self.sender_lock.release()
   return
Exemple #9
0
 def send_helper(self, msg):
     while self.sender_state == config.WAIT_FOR_ACK_MSG:
         # sleep here so less busy waiting.
         time.sleep(0.01)
     packet = util.make_packet(msg, config.MSG_TYPE_DATA,
                               self.sequence_number)
     packet_data = util.extract_data(packet)
     self.sender_lock.acquire()
     util.log("Sending data: " + util.pkt_to_string(packet_data))
     self.network_layer.send(packet)
     self.last_pkt_sent = packet
     self.last_pkt_sent_data = packet_data
     self.sender_state = config.WAIT_FOR_ACK_MSG
     self.set_timer()
     self.timer.start()
     self.sender_lock.release()
     return
Exemple #10
0
 def _send_helper(self, msg):
     self.sender_lock.acquire()
     packet = util.make_packet(
         msg, config.MSG_TYPE_DATA, self.next_sequence_number
     )  # LLamo a la funcion para armar el paquete en util
     packet_data = util.extract_data(
         packet
     )  # LLamo a la funcion para extraer los datos y recibir el RDTPacket
     self.window[self.next_sequence_number % config.WINDOW_SIZE] = packet
     util.log("Sending data: " + util.pkt_to_string(packet_data))
     self.network_layer.send(
         packet)  #Llama a la funcion para enviar el paquete
     if self.sender_base == self.next_sequence_number:
         if self.timer.is_alive(): self.timer.cancel()
         self.set_timer()
         self.timer.start()
     self.next_sequence_number += 1
     self.sender_lock.release()
     return
Exemple #11
0
 def _timeout(self, *args):
     packet = args[0]
     seq_num = args[1]
     self.sender_lock.acquire()
     packet_data = util.extract_data(packet)
     util.log("Timeout! Resending packet: " +
              util.pkt_to_string(packet_data))
     window_index = (
         seq_num - self.sender_base
     ) % config.WINDOW_SIZE  # window_index is the index to the acked_flag_list and timer_list for a particular packet
     current_timer = self.timer_list[window_index]  # cancel the old thread
     if current_timer:
         current_timer.cancel()
     self.set_timer(packet,
                    packet_data.seq_num)  # set up a new timer thread
     self.network_layer.send(packet)
     self.timer_list[window_index].start()
     self.sender_lock.release()
     return
Exemple #12
0
 def _send_helper(self, msg):
     self.sender_lock.acquire()
     packet = util.make_packet(msg, config.MSG_TYPE_DATA,
                               self.next_sequence_number)
     packet_data = util.extract_data(packet)
     util.log("Sending data: " + util.pkt_to_string(packet_data))
     self.network_layer.send(packet)
     if self.next_sequence_number < self.sender_base + config.WINDOW_SIZE:
         packet_offset_index = (self.next_sequence_number -
                                self.sender_base) % config.WINDOW_SIZE
         print(packet_offset_index)
         self.sender_buffer[packet_offset_index] = packet
         self.ack_list[packet_offset_index] = False
         self.timer_list[packet_offset_index] = self.set_timer(
             self.next_sequence_number)
         self.timer_list[packet_offset_index].start()
         self.next_sequence_number += 1
     else:
         pass
     self.sender_lock.release()
     return
Exemple #13
0
 def _send_helper(self, msg):
     self.sender_lock.acquire()
     packet = util.make_packet(msg, config.MSG_TYPE_DATA,
                               self.next_sequence_number)
     packet_data = util.extract_data(packet)
     window_index = (
         self.next_sequence_number - self.sender_base
     ) % config.WINDOW_SIZE  # window_index is the index to the acked_flag_list and timer_list for a particular packet
     util.log("Sending data: " + util.pkt_to_string(packet_data))
     self.network_layer.send(packet)
     self.acked_flag_list[
         window_index] = False  # packet delivered to network layer, set the ACK flag to False
     current_timer = self.timer_list[
         window_index]  # retrieve any old timer thread
     if current_timer:  # if timer thread exist
         current_timer.cancel()  # cancel the thread
     self.set_timer(packet,
                    self.next_sequence_number)  # set up a new timer thread
     self.timer_list[window_index].start()
     self.next_sequence_number += 1
     self.sender_lock.release()
     return
Exemple #14
0
    def handle_arrival_msg(self):
        msg = self.network_layer.recv()
        msg_data = util.extract_data(msg)

        if (msg_data.is_corrupt):
            return

        # If ACK message, assume its for sender
        if msg_data.msg_type == config.MSG_TYPE_ACK:
            self.sender_lock.acquire()
            packet_offset_index = (msg_data.seq_num -
                                   self.sender_base) % config.WINDOW_SIZE
            print(packet_offset_index)
            self.ack_list[packet_offset_index] = True
            print('sender cancel timer after receiving ack')

            util.log("Received ACK with seq #" + util.pkt_to_string(msg_data) +
                     ". Cancelling timer.")
            self.timer_list[packet_offset_index].cancel()
            self.timer_list[packet_offset_index] = self.set_timer(
                msg_data.seq_num)

            for timer in self.timer_list:
                print(timer.is_alive())

            # check if the packet right after sendbase is ack'd
            # if yes, move sendbase
            # update the arrays (timer_list, ack_list) accordingly
            # by removing first element, and add empty timer, and False ack
            try:
                while self.ack_list[0] == True:
                    self.sender_base += 1
                    util.log(f"Updated send base to {self.sender_base}")
                    self.ack_list = self.ack_list[1:] + [False]
                    self.timer_list = self.timer_list[1:] + [
                        self.set_timer(-1)
                    ]
                    self.sender_buffer = self.sender_buffer[1:] + [b'']
            except IndexError:
                pass

            self.sender_lock.release()

        # If DATA message, assume its for receiver
        else:
            assert msg_data.msg_type == config.MSG_TYPE_DATA
            util.log("Received DATA: " + util.pkt_to_string(msg_data))

            ack_pkt = util.make_packet(b'', config.MSG_TYPE_ACK,
                                       msg_data.seq_num)

            if msg_data.seq_num in range(
                    self.receiver_base,
                    self.receiver_base + config.WINDOW_SIZE):
                self.network_layer.send(ack_pkt)
                util.log("Sent ACK: " +
                         util.pkt_to_string(util.extract_data(ack_pkt)))
                packet_offset_index = (msg_data.seq_num -
                                       self.receiver_base) % config.WINDOW_SIZE
                self.rcv_list[packet_offset_index] = True

                if msg_data.seq_num != self.receiver_base:
                    # Append the payload
                    self.rcv_buffer[packet_offset_index] = msg_data.payload

                else:
                    # Append the payload
                    self.rcv_buffer[packet_offset_index] = msg_data.payload
                    while self.rcv_list[0] == True:
                        self.msg_handler(self.rcv_buffer[0])
                        self.receiver_base += 1
                        self.rcv_list = self.rcv_list[1:] + [False]
                        self.rcv_buffer = self.rcv_buffer[1:] + [b'']
                        util.log(
                            f"Updated receiver base to {self.receiver_base}")

            elif msg_data.seq_num < self.receiver_base:

                self.network_layer.send(ack_pkt)
                util.log("Packet outside receiver window")
                util.log("Sent ACK: " +
                         util.pkt_to_string(util.extract_data(ack_pkt)))

            else:
                return

        return
Exemple #15
0
    def handle_arrival_msg(self):
        msg = self.network_layer.recv()
        msg_data = util.extract_data(msg)

        if (msg_data.is_corrupt):
            # do nothing
            # receiver should not send out ACK packet
            # sender should ignore ACK packet, and wait for timeout to resend packet
            util.log("Message corrupted: " + util.pkt_to_string(msg_data))
            return

        # If ACK message, assume its for sender
        if msg_data.msg_type == config.MSG_TYPE_ACK:
            self.sender_lock.acquire()
            util.log("Received ACK: " + util.pkt_to_string(msg_data))
            target_window_index = (msg_data.seq_num -
                                   self.sender_base) % config.WINDOW_SIZE
            self.acked_flag_list[
                target_window_index] = True  # set the ACKed flag to True
            current_timer = self.timer_list[
                target_window_index]  # retrieve timer thread for the packet
            if current_timer:
                current_timer.cancel()  # cancel the timer
            cumulative_acks = 0  # initialize a variable to check cumulative ACKed packet starting from sender_base
            for hasACKed in self.acked_flag_list:
                if hasACKed:
                    cumulative_acks += 1
                else:
                    break
            if cumulative_acks > 0:  # if has cumulative ACKed packets, slide sender window forward by
                self.timer_list = self.timer_list[
                    cumulative_acks:]  # removing the timer and ACKed flag that falls out from window
                self.acked_flag_list = self.acked_flag_list[cumulative_acks:]
                for i in range(cumulative_acks):  # add new default value to
                    self.timer_list.append(None)  # timer list
                    self.acked_flag_list.append(False)  # ACKed flag list
            self.sender_lock.release()
            self.sender_base += cumulative_acks  # update sender_base

        # If DATA message, assume its for receiver
        else:
            assert msg_data.msg_type == config.MSG_TYPE_DATA
            util.log("Received DATA: " + util.pkt_to_string(msg_data))
            if (
                    self.receiver_base - config.WINDOW_SIZE <= msg_data.seq_num
                    <= self.receiver_base - 1
            ):  # if packet has seq_num in range [receiver_base-N,receiver_base-1]
                ack_pkt = util.make_packet(b'', config.MSG_TYPE_ACK,
                                           msg_data.seq_num)  # send ACK
                self.network_layer.send(ack_pkt)
                util.log("Send ACK for seq# : " +
                         util.pkt_to_string(util.extract_data(ack_pkt)))
            if (msg_data.seq_num >= self.receiver_base
                ):  # if packet has seq_num larger than receiver_base
                ack_pkt = util.make_packet(b'', config.MSG_TYPE_ACK,
                                           msg_data.seq_num)
                self.network_layer.send(ack_pkt)
                util.log("Send ACK for seq# : " +
                         util.pkt_to_string(util.extract_data(ack_pkt)))
                util.log("Added DATA wtih seq# : " + str(msg_data.seq_num) +
                         ' to buffer.')
                target_window_index = (msg_data.seq_num -
                                       self.receiver_base) % config.WINDOW_SIZE
                self.receiver_buffer[
                    target_window_index] = msg_data.payload  # add packet to buffer
                self.received_flag_list[
                    target_window_index] = True  # set received flag to True
            cumulative_seqs = 0  # initialize a variable to check cumulative seq_num in receiver_buffer
            for hasReceived in self.received_flag_list:
                if hasReceived:
                    cumulative_seqs += 1
                else:
                    break
            if (cumulative_seqs >
                    0):  # if receiver has cumulative sequence of packets
                for i in range(cumulative_seqs):
                    self.msg_handler(
                        self.receiver_buffer[i]
                    )  # pass the sequence of packets to application layer
                self.receiver_buffer = self.receiver_buffer[
                    cumulative_seqs:]  # remove delivered packet from buffer
                self.received_flag_list = self.received_flag_list[
                    cumulative_seqs:]  # and their respective received status
                for i in range(cumulative_seqs):  # add new default value for
                    self.receiver_buffer.append(None)  # receiver buffer
                    self.received_flag_list.append(False)  # received flag list
            self.receiver_base += cumulative_seqs  # update receiver_base
        return