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
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
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
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
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
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
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
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
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
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
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
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
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
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
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