def ack_recv_thread_func(self): """ Thread function for receiving client acks and updating window base accordingly. Also responsible for receiving EOT packets from client and changing state for main thread. """ ack_socket = socket(AF_INET, SOCK_DGRAM) ack_socket.bind((self.hostname, self.ack_port)) while not self.eot: try: # Parse Packet data, port = ack_socket.recvfrom(constants.ACK_BUFFER_SIZE) p = packet.parse_udp_data(data) # Packet is ACK if p.type == constants.TYPE_ACK: logger.log(f"Received ack with seq: {p.seq_num}") logger.ack(p.seq_num) self.next_seq_num = p.seq_num self.window.update_base_number(self.next_seq_num) # Packet is EOT if p.type == constants.TYPE_EOT: self.eot = True logger.log("Received EOT.") except TypeError as e: logger.log(f"Received data that could not be processed: {e}.")
def receive(self, emulator_addr, emulator_port): # print("begin to receive -----------------") while True: rcv_data, address = self.rcv_udp_socket.recvfrom(1024) # print("receive a new packet ------------------") rcv_packet = packet.parse_udp_data(rcv_data) # print("receive pkt seq_num" + str(rcv_packet.seq_num)) expected_num = self.expected_seq_num % SEQ_NUM_MODULO if rcv_packet.seq_num == expected_num: if rcv_packet.type == 2: # print("receive all data and begin to send EOT -----------------------") msg = packet.create_eot(rcv_packet.seq_num).get_udp_data() self.send_udp_socket.sendto(msg, (emulator_addr, emulator_port)) self.send_udp_socket.close() self.rcv_udp_socket.close() break elif rcv_packet.type == 1: self.expected_seq_num += 1 self.data_list.append(rcv_packet.data) self.arrival_log.append(rcv_packet.seq_num) if self.expected_seq_num != 0: # print("begin to send ACK ------------------") cur_ack_num = (self.expected_seq_num - 1) % SEQ_NUM_MODULO # print("send ack" + str(cur_ack_num)) ack_msg = packet.create_ack(cur_ack_num).get_udp_data() self.send_udp_socket.sendto(ack_msg, (emulator_addr, emulator_port))
def receive(self): # print("begin to reveive -----------------") while True: rcv_data , address = self.rcv_udp_socket.recvfrom(4096) rcv_ack = packet.parse_udp_data(rcv_data) if rcv_ack.type == 2: # receiver has received all packet # print("receive all packet, end receive ---------------") self.transmission_time = time.time() - self.start_time self.lock.acquire() self.STOP_SIGN = True self.lock.release() break elif rcv_ack.type == 0: self.ack_log.append(rcv_ack.seq_num) # print("rcv pkt :" + str(rcv_ack.seq_num)) distance_base_rcv = 0 base = self.send_base % SEQ_NUM_MODULO if base < rcv_ack.seq_num: # [3(base), 4, 5, 6(rcv_ack), 7, 8(next_seq_num), 9 ...] # [31(rcv_ack), 0(base), 1, 2, 3(next_seq_num), 4 ...] distance_base_rcv = rcv_ack.seq_num - base + 1 elif base > rcv_ack.seq_num: # [30(base), 31, 0, 1, 2(rcv_ack), 3, 4, 5(next_seq_num), 6, ...] # [29(rcv_ack), 30(base), 31, 0, 1, 2(next_seq_num), 3...] distance_base_rcv = rcv_ack.seq_num + SEQ_NUM_MODULO - base + 1 # update base based on rcv pkt seq num and update timer as well if distance_base_rcv < WINDOW_SIZE: # print("move slide window -------from" + str(self.send_base) +" to " + str (self.send_base+distance_base_rcv) ) self.send_base += distance_base_rcv self.lock.acquire() self.base_time = time.time() self.lock.release()
def RecSendAck(EmulatorHostName, EmulatorPortNumAckFrRec, RecPortNumRecDataFroE, FileNameToWriteData): receiverSocket = socket(AF_INET, SOCK_DGRAM) receiverSocket.bind(('', RecPortNumRecDataFroE)) while True: packet_rec_udp, clientAddress = receiverSocket.recvfrom(2048) # parse the recieved packet packet_rec = packet.parse_udp_data(packet_rec_udp) seq_num_rec = packet_rec.seq_num # if the packet is not EOT, record in the arrival log if (packet_rec.type != 2): arrival_to_write = "{}{}".format(seq_num_rec, '\n') arrival_log.write(arrival_to_write) # deal with the first packet's seq num is not the seq num = 0 situation if (len(rec_seq_num) == 0 and seq_num_rec != 0): continue # receive the first expected packet if (len(rec_seq_num) == 0): rec_seq_num.append(seq_num_rec) Ack_packet = packet.create_ack(seq_num_rec) f.write(packet_rec.data) receiverSocket.sendto(Ack_packet.get_udp_data(), (EmulatorHostName, EmulatorPortNumAckFrRec)) continue #receive the EOT packet if ((packet_rec.type == 2)): EOT_packet = packet.create_eot(seq_num_rec) receiverSocket.sendto(EOT_packet.get_udp_data(), (EmulatorHostName, EmulatorPortNumAckFrRec)) arrival_log.close() receiverSocket.close() f.close() break #not receive the expected packet if (seq_num_rec != (((rec_seq_num[len(rec_seq_num) - 1] + 1) % SEQ_NUM_MODULO))): Ack_packet = packet.create_ack(rec_seq_num[len(rec_seq_num) - 1]) receiverSocket.sendto(Ack_packet.get_udp_data(), (EmulatorHostName, EmulatorPortNumAckFrRec)) continue #receive the expected packet if (seq_num_rec == (((rec_seq_num[len(rec_seq_num) - 1] + 1) % SEQ_NUM_MODULO))): rec_seq_num.append(seq_num_rec) Ack_packet = packet.create_ack(seq_num_rec) f.write(packet_rec.data) receiverSocket.sendto(Ack_packet.get_udp_data(), (EmulatorHostName, EmulatorPortNumAckFrRec)) continue
def receiveACK(client_udp_sock): global send_base, terminate, timer_base while not terminate: msg, _ = client_udp_sock.recvfrom(4096) ack_packet = packet.parse_udp_data(msg) ack_seq_num = ack_packet.seq_num ack_type = ack_packet.type # if received an ack for EOT, exit if ack_type == 2: lock.acquire() terminate = True lock.release() break ack_log.append(ack_packet.seq_num) distance = 0 if send_base % SEQ_MODULO < ack_seq_num: distance = ack_seq_num - send_base % SEQ_MODULO elif send_base % SEQ_MODULO > ack_seq_num: distance = ack_seq_num + SEQ_MODULO - send_base % SEQ_MODULO if distance < WINDOW_SIZE: # update the base send_base += distance + 1 lock.acquire() timer_base = time.time() # update the timer base time lock.release()
def receive(filename, emulatorAddr, emuReceiveACK, client_udp_sock): global expected_pkt_num save_data = bytearray() try: file = open(filename, 'wb') except IOError: print('Unable to open', filename) return while True: msg, _ = client_udp_sock.recvfrom(4096) data_packet = packet.parse_udp_data(msg) packet_type = data_packet.type seq_num = data_packet.seq_num data = data_packet.data arrival_log.append(seq_num) # receives EOT, send EOT back and exit if packet_type == 2 and seq_num == expected_pkt_num % SEQ_MODULO: client_udp_sock.sendto(packet.create_eot(seq_num).get_udp_data(), (emulatorAddr, emuReceiveACK)) break # receives expected data packet if seq_num == expected_pkt_num % SEQ_MODULO: expected_pkt_num += 1 save_data.extend(data.encode()) # if the very first data packet #0 get lost, do not ACK and wait for a timeout resend. if expected_pkt_num != 0: ack_num = (expected_pkt_num - 1) % SEQ_MODULO client_udp_sock.sendto(packet.create_ack(ack_num).get_udp_data(), (emulatorAddr, emuReceiveACK)) file.write(save_data) file.close()
def GetAck(SenderPortNumRecAckFroE): # sender receive the ACK through AckRec Socket AckRecSocket = socket(AF_INET, SOCK_DGRAM) AckRecSocket.bind(('', SenderPortNumRecAckFroE)) global SeqNumSentNotAck global PacketSentNotAck while True: udp_packet, EmulatorAddress = AckRecSocket.recvfrom(2048) packet_rec = packet.parse_udp_data(udp_packet) AckSeq = packet_rec.seq_num type = packet_rec.type #check if it is EOT, if not record the seq num if (type != 2): ack_num_to_write = "{}{}".format(AckSeq, '\n') ack_log.write(ack_num_to_write) SeqNumAck.append(AckSeq) # receive EOT if (type == 2): seq_num_log.close() ack_log.close() time.sleep(0.2) AckRecSocket.close() break # deal with duplicate ack and the first seq not equal to 0 if (len(SeqNumSentNotAck) == 0) or (AckSeq not in SeqNumSentNotAck): continue # slide the window and restart the timer if (SeqNumSentNotAck.index(AckSeq) >= 0): if (AckSeq in SeqNumSentNotAck): index = SeqNumSentNotAck.index(AckSeq) SeqNumSentNotAck = SeqNumSentNotAck[(index + 1):] PacketSentNotAck = PacketSentNotAck[(index + 1):] if (len(SeqNumSentNotAck)) != 0: signal.setitimer(signal.ITIMER_REAL, Timeout) else: # if there are no packets in the window, stop the timer signal.setitimer(signal.ITIMER_REAL, 0) else: continue
def run(self): udp_socket_receive = socket(AF_INET, SOCK_DGRAM) udp_socket_receive.bind(('', self.udp_port_data)) udp_socket_send = socket(AF_INET, SOCK_DGRAM) while True: #print("waitting...") row_data, clientAddress = udp_socket_receive.recvfrom( 1024) #1024 if buffer size received_packet = packet.parse_udp_data(row_data) #print("except seqnum: " + str(self.get_expect_squnum())) #print("actual seqnum: " + str(received_packet.seq_num)) #print(received_packet.data) if received_packet.type == 1: self.log(str(received_packet.seq_num)) if (received_packet.seq_num == self.get_expect_squnum()): self.expect_seqnum += 1 if received_packet.type == 1: if (self.expect_seqnum - 1) == 0: with open(self.file_to_write, "w+") as f: f.write(received_packet.data) else: with open(self.file_to_write, "a") as f: f.write(received_packet.data) #last acked pkt's seqnum is excepted next seqnum - 1 packet_to_send = packet.create_ack( self.get_expect_squnum() - 1) #print("send ack: "+ str(packet_to_send.seq_num)) udp_socket_send.sendto( packet_to_send.get_udp_data(), (self.host_address, self.udp_port_ack)) else: #if the last pkt is not what we want, #resend the lastest acked seqnum #last acked pkt's seqnum is excepted next seqnum - 1 if self.expect_seqnum != 0: packet_to_send = packet.create_ack( self.get_expect_squnum() - 1) #print("send previous ack: "+ str(packet_to_send.seq_num)) udp_socket_send.sendto( packet_to_send.get_udp_data(), (self.host_address, self.udp_port_ack)) elif received_packet.type == 2: packet_to_send = packet.create_eot(self.get_expect_squnum()) udp_socket_send.sendto(packet_to_send.get_udp_data(), (self.host_address, self.udp_port_ack)) #print("eot seqnum: " + str(packet_to_send.seq_num)) udp_socket_send.close() break
def genACKReceiver(portNumber): # print("Listening for ACKs on Port: %d" % portNumber) # Create new UDP socket and bind to a randomly assigned avaliable port global lastAckSeqNum global lastAckChanged global noMoreAck # create ack receiver port based on supplied port number rSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) rSocket.bind(('', portNumber)) # start listening for ack packets while True: noMoreAckLock.acquire() # check if main thread ended if noMoreAck: noMoreAckLock.release() return noMoreAckLock.release() try: ackMessage = rSocket.recv(1024) except: # Error case, the connection is lost or the message is invalid sys.exit(3) ackPackage = packet.parse_udp_data(ackMessage) # process all ack packet if (ackPackage.type == 0): # print("New ack: %d" % ackPackage.seq_num) # print("Last ack: %d" % lastAckSeqNum) # write the received ack packet to log file with open('ack.log', 'a+') as file: file.write("%d\n" % ackPackage.seq_num) file.close() # only update last received ack packet sequence number # when a new different ack is received seqNumLock.acquire() ackDiff = ackPackage.seq_num - lastAckSeqNum if ackDiff > 0: lastAckSeqNum = ackPackage.seq_num lastAckChanged = True elif ackDiff >= -31 and ackDiff <= -23: lastAckSeqNum = ackPackage.seq_num lastAckChanged = True seqNumLock.release()
def ack(startpoint, endpoint): global N global packets global packetsSent global senderSocket # start timer startTime = time.time() temporarySent = 0 offset = 0 startPacket = startpoint % packet.SEQ_NUM_MODULO - 1 endPacket = endpoint % packet.SEQ_NUM_MODULO while packetsSent + temporarySent < endpoint: # packets sent and acked, WAIT ON UDP listResult = select.select([senderSocket], [], [], 0.15) if not listResult[0]: # if did not return in time packetsSent = packetsSent + temporarySent print("seqnum, packets acked, startPacket: ", p.seq_num, packetsSent, startPacket) return UDPdata, clientAddress = senderSocket.recvfrom(2048) p = packet.parse_udp_data(UDPdata) if p.seq_num > startPacket: offset = p.seq_num - startPacket else: offset = (N - startPacket) + p.seq_num if offset > temporarySent: print("new offset: ", offset) temporarySent = offset # if taken longer than 150 ms return if time.time() - startTime > 0.15: packetsSent = packetsSent + temporarySent print("seqnum, packets acked, startPacket: ", p.seq_num, packetsSent, startPacket) return # return if all packets acked packetsSent = packetsSent + temporarySent print("seqnum, packets acked, startPacket: ", p.seq_num, packetsSent, startPacket) return
def verify_ack(self): udp_socket = socket(AF_INET, SOCK_DGRAM) udp_socket.bind(('', self.udp_port_ack)) is_first_ack = True while True: #waiting ack row_data, clientAddress = udp_socket.recvfrom(1024) #1024 if buffer size received_packet = packet.parse_udp_data(row_data) if received_packet.type == 0: self.lock_window.acquire() #print("ack: seq_num "+str(received_packet.seq_num)) #print("base: "+str(self.base)) self.log_receive(str(received_packet.seq_num)) #define base_seqnum = 1 which represent the relationship #between base and new acked seqnum last_sent_seqnum = (self.next_seqnum-1)%self.SEQ_NUM_MODULO base_seqnum_type = 3 #should not be acked if 3 if (self.base <= received_packet.seq_num and received_packet.seq_num <= last_sent_seqnum) or\ (self.base > last_sent_seqnum and received_packet.seq_num >= self.base): base_seqnum_type = 1 #not cross 31 elif (self.base > last_sent_seqnum and received_packet.seq_num <= last_sent_seqnum): base_seqnum_type = 2 #cross 31 else: base_seqnum_type = 3 #not valid ack seqnum #delete the packet form window with the right seq_num, len_window = len(self.window) i = 0 while i < len_window: if (base_seqnum_type == 1 and self.window[i].seq_num <= received_packet.seq_num and self.window[i].seq_num >= self.base) or \ (base_seqnum_type == 2 and (self.window[i].seq_num >= self.base or self.window[i].seq_num <= received_packet.seq_num)): pkt=self.window.pop(i) #print("delete: " + str(pkt.seq_num)) len_window -= 1 else: i += 1 #update base if base_seqnum_type != 3: self.base = (received_packet.seq_num + 1)%self.SEQ_NUM_MODULO #print(self.window) #if there is still some packet sent but not acked #set timer for one of them if len(self.window) != 0: self.set_timer() self.lock_window.release() elif received_packet.type == 2: #print("ack: eot seq_num "+str(received_packet.seq_num)) break
def ACK_receiver(portNumber): # Call global variable global last_ACKed_Seqnum global last_ACKed_Changed global rest_ACK # Create new UDP socket and bind to avaliable port receiver_Socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Create ACK receiver port receiver_Socket.bind(('', portNumber)) # Start waiting for ACK while True: rest_ACK_lock.acquire() # Check if main thread ended if rest_ACK: rest_ACK_lock.release() return rest_ACK_lock.release() try: ACK_status = receiver_Socket.recv(1024) except: # Error case, the connection is lost or the message is invalid sys.exit(3) ACK_packet = packet.parse_udp_data(ACK_status) # Start receving ACK if (ACK_packet.type == 0): # Record ACK sequence number with open('ack.log', 'a+') as file: file.write("%d\n" % ACK_packet.seq_num) file.close() # Update last received ACK sequence number seqnum_lock.acquire() ACK_diff = ACK_packet.seq_num - last_ACKed_Seqnum if ACK_diff > 0: last_ACKed_Seqnum = ACK_packet.seq_num last_ACKed_Changed = True elif (ACK_diff >= (-31)) and (ACK_diff <= (-23)): last_ACKed_Seqnum = ACK_packet.seq_num last_ACKed_Changed = True seqnum_lock.release()
def receive(self): while True: recv_data, address = self.udp_socket.recvfrom(4096) recv_packet = packet.parse_udp_data(recv_data) # print('recv ack: ', recv_packet.seq_num) self.ack_log.append(recv_packet.seq_num) if recv_packet.type == 2: self.time_log.append(time.time()) # print('EOT. WRITE LOG.') for ack in self.ack_log: self.ack_log_file.write(str(ack) + '\n') self.ack_log_file.close() print(self.time_log[1] - self.time_log[0]) self.time_log_file.write( str(abs(self.time_log[1] - self.time_log[0]))) self.time_log_file.close() for num in self.seqnum_log: self.seqnum_log_file.write(str(num) + '\n') self.seqnum_log_file.close() # print('ack_log:', self.ack_log) # print('time_log:', self.time_log[1] - self.time_log[0]) # print('seqnum_log:', self.seqnum_log) os._exit(0) self.lock.acquire() if (self.next_ack + self.WINDOW_SIZE) % self.SEQ_NUM_MODULO > self.next_ack: if recv_packet.seq_num >= self.next_ack and recv_packet.seq_num < self.next_ack + self.WINDOW_SIZE: self.next_ack = (recv_packet.seq_num + 1) % self.SEQ_NUM_MODULO else: if recv_packet.seq_num >= self.next_ack or recv_packet.seq_num < ( self.next_ack + self.WINDOW_SIZE) % self.SEQ_NUM_MODULO: self.next_ack = (recv_packet.seq_num + 1) % self.SEQ_NUM_MODULO self.lock.release()
def handle_message(self, socket) -> packet: """ Handles the receiving of packets, sending acks and storing data locally. Args: socket: The socket to receive data from. Returns: The parsed packet object of the most recent message. """ message, _ = socket.recvfrom(constants.PACKET_DATA_SIZE) try: p = packet.parse_udp_data(message) except Exception as e: logger.log(f"ERROR: {e}") return None logger.log( f"Received packet with no: {p.seq_num}." f"Looking for {(self.seq_num + 1) % constants.MODULO_RANGE}") if p.type == constants.TYPE_EOT: logger.log("Received EOT.") return p elif p.type == constants.TYPE_ACK: # Should not happened logger.log("[ERROR] Received ACK.") return p # Else data message logger.arrival(p.seq_num) if p.seq_num == (self.seq_num + 1) % constants.MODULO_RANGE: # Expected, next packet with open(self.filename, "a") as f: f.write(p.data) self.send_ack(self.seq_num) logger.log( f"Sending ACK for good packet with no: {self.seq_num + 1}") self.seq_num = p.seq_num else: self.send_ack(self.seq_num) logger.log(f"Sending ACK for bad packet with no: {self.seq_num}") return p
def ack(): global N global senderSocket global base global nextseqnum global timer global ackfile while True: UDPdata, clientAddress = senderSocket.recvfrom(2048) p = packet.parse_udp_data(UDPdata) ackfile.write(str(p.seq_num) + "\n") lastBase = base baseModulo = base % packet.SEQ_NUM_MODULO currSeqnum = p.seq_num windowEnd = (baseModulo + N - 1) % packet.SEQ_NUM_MODULO if p.type == 2: senderSocket.close() break # check if within valid range if currSeqnum >= baseModulo and currSeqnum <= windowEnd: base = base + currSeqnum - baseModulo + 1 elif baseModulo > windowEnd and (currSeqnum <= windowEnd or currSeqnum >= baseModulo): if baseModulo <= currSeqnum: base = base + currSeqnum + 1 - baseModulo else: base = base + currSeqnum + 1 + (packet.SEQ_NUM_MODULO - baseModulo) if base > lastBase: if base != nextseqnum: timer = time.time() else: timer = None
def receive(udpSocket, emulator_hostname, emulator_port, sender_port): # print("sender_port: ", sender_port) # udpSocket.bind(('', int(sender_port))) current_seq_num = -1 first_packet = False global window_location while True: #receive packet from receiver (ACK/EOT) data, address = udpSocket.recvfrom(2048) packet_received = packet.parse_udp_data(data) if current_seq_num != packet_received.seq_num: first_packet = True current_seq_num = packet_received.seq_num if packet_received.type == 0: #receive ACK sequence_number_acked = packet_received.seq_num # print("sender receive: " + str(sequence_number_acked)) #write into ack.log file_ack = open("ack.log", "a") file_ack.write(str(sequence_number_acked) + "\n") file_ack.close() #update window_states window_lock.acquire() current_window_size = len(window) for x in range(current_window_size): window_states[x] = 2 packet_cur = window[x] packet_cur_seq_num = packet_cur.seq_num if packet_cur_seq_num == sequence_number_acked: break #update window & window_states counter = 0 for x in range(current_window_size): state_cur = window_states[x] if state_cur == 2: counter += 1 else: break for x in range(counter): window.pop(0) window_states.pop(0) window_location += 1 # print("after receive: ", window_states) # print_window_seq_num() #check if need to restart/stop timer current_window_size = len(window) check_flag = True for x in range(current_window_size): if window_states[x] != 2: check_flag = False break window_lock.release() if check_flag == True: timer.stop_timer() else: timer.start_timer() elif packet_received.type == 2: #receive EOT # print("receive eot") global end_time end_time = time.time() file_ack = open("ack.log", "a") file_ack.write(str(packet_received.seq_num) + "\n") file_ack.close() break else: print("This should not happen. Something is wrong. -2") sys.exit() elif first_packet == False: continue
def main(args): # Check the number of arguments is correct or not if not len(args) == 5: print('Error 2: expected 5 arguments, %d was received' % (len(args))) sys.exit(2) # Check if the type of argument is correct if (not ((args[2]).isdigit())) or (not ((args[3]).isdigit())): print('Error 4: port number must be an integer') sys.exit(4) # Get arguments naddr = args[1] host_port = int(args[2]) file_port = int(args[3]) file_name = args[4] # Open files file = open(file_name, 'w+') Arrive_log = open('arrival.log', 'w+') # Create receiving packet receiver_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) receiver_socket.bind(('', file_port)) # Define useful variables next_seqnum = 0 counter = 0 first = True # Start receving packets while True: try: data_pkt = receiver_socket.recv(1024) except: print('Error: paeket error') sys.exit(2) # Process received packet data_packet = packet.parse_udp_data(data_pkt) # Recevied packet is file data if data_packet.type == 1: # Record received packet sequence number Arrive_log.write('%d\n' % data_packet.seq_num) # Update expected sequence number and write data to file if the sequence is expected if data_packet.seq_num == next_seqnum: file.write(data_packet.data) next_seqnum += 1 next_seqnum = next_seqnum % packet.SEQ_NUM_MODULO ACK_pkt = packet.create_ack(data_packet.seq_num) first = False # Otherwise, ignore and resend the last/duplicate ACK else: last_ACK_seqnum = next_seqnum - 1 if (last_ACK_seqnum < 0): last_ACK_seqnum = 31 ACK_pkt = packet.create_ack(last_ACK_seqnum) # Stop sending any ACK if it is first time and sequence number is not expected if not first: receiver_socket.sendto(ACK_pkt.get_udp_data(), (naddr, host_port)) counter += 1 # Recevied packet is EOT elif data_packet.type == 2: receiver_socket.sendto( packet.create_eot(next_seqnum - 1).get_udp_data(), (naddr, host_port)) sys.exit(0) # Close files file.close() Arrive_log.close()
def main(commandlineArgs): # check if correct number of arguments is supplied if not len(commandlineArgs) == 5: print('Error: the number of parameter supplied is incorrect') sys.exit(2) hostAddr = commandlineArgs[1] hostPort = int(commandlineArgs[2]) recvPort = int(commandlineArgs[3]) fileName = commandlineArgs[4] # open log file and to-be-saved file file = open(fileName, 'w+') arrivalLog = open('arrival.log', 'w+') # create packet receiving packet rSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) rSocket.bind(('', recvPort)) expectedSeqNum = 0 firstRun = True # print('Listenning on port: %d' % recvPort) count = 0 # start listening for packets while True: try: udpData = rSocket.recv(1024) except: print('Error: package error') sys.exit(2) # print('new packet') # process received packet dataPackage = packet.parse_udp_data(udpData) # the received packet is data if dataPackage.type == 1: # print('New packet: %d' % dataPackage.seq_num) # print('Expected: %d' % expectedSeqNum) # write newly received packet sequence number to log file arrivalLog.write('%d\n' % dataPackage.seq_num) # if the packet received has the expected sequence number # update expected sequence number and write data to file if dataPackage.seq_num == expectedSeqNum: file.write(dataPackage.data) expectedSeqNum += 1 expectedSeqNum = expectedSeqNum % packet.SEQ_NUM_MODULO ackPkg = packet.create_ack(dataPackage.seq_num) firstRun = False else: # packet sequence number is not expected # resend ack packet with last received sequence number lastAckSeqNum = expectedSeqNum - 1 if (lastAckSeqNum < 0): lastAckSeqNum = 31 ackPkg = packet.create_ack(lastAckSeqNum) # if it's first run and packet sequence number is not correct # don't send any ack packet if not firstRun: rSocket.sendto(ackPkg.get_udp_data(), (hostAddr, hostPort)) count += 1 elif dataPackage.type == 2: # packet type is eot, send a eot packet then exit rSocket.sendto( packet.create_eot(expectedSeqNum - 1).get_udp_data(), (hostAddr, hostPort)) sys.exit(0)
def main(): #get arguments emulator_hostname = sys.argv[1] emulator_port = sys.argv[2] receiver_port = sys.argv[3] output_file = sys.argv[4] #create udp connection to emulator udpSocket = socket(AF_INET, SOCK_DGRAM) udpSocket.bind(('', int(receiver_port))) #set up needed variables expected_sequence_number = 0 current_sequence_number = -1 first_packet = False #clean output file open("arrival.log", "w").close() open("output.txt", "w").close() #receive packet from emulator while True: udp_data, address = udpSocket.recvfrom(2048) packet_received = packet.parse_udp_data(udp_data) sequence_number = packet_received.seq_num #write into arrival.log # print("receiver receives: " + str(sequence_number)) if packet_received.type == 1: file_arrival = open("arrival.log", "a") file_arrival.write(str(sequence_number) + "\n") file_arrival.close() if sequence_number == expected_sequence_number: first_packet = True if packet_received.type == 1: packet_to_send = packet.create_ack(sequence_number) packet_to_send_encode = packet_to_send.get_udp_data() udpSocket.sendto(packet_to_send_encode, (emulator_hostname, int(emulator_port))) # print("receiver ack: " + str(packet_to_send.seq_num)) current_sequence_number = sequence_number expected_sequence_number = (1 + sequence_number) % 32 data = packet_received.data file_output = open(output_file, "a") file_output.write(data) file_output.close() elif packet_received.type == 2: # print("receive eot") packet_to_send = packet.create_eot(sequence_number) packet_to_send_encode = packet_to_send.get_udp_data() udpSocket.sendto(packet_to_send_encode, (emulator_hostname, int(emulator_port))) file_arrival = open("arrival.log", "a") file_arrival.write(str(packet_to_send.seq_num) + "\n") file_arrival.close() # print("receiver ack: " + str(packet_to_send.seq_num)) udpSocket.close() sys.exit() elif first_packet == False: continue else: packet_to_send = packet.create_ack(current_sequence_number) packet_to_send_encode = packet_to_send.get_udp_data() udpSocket.sendto(packet_to_send_encode, (emulator_hostname, int(emulator_port)))
recv_socket = socket(AF_INET, SOCK_DGRAM) recv_socket.bind(('', recv_port)) expected_seq_num = 0 cur_packet_seq_num = 0 done_first_packet = False # for detecting first packet with seq num 0 out_file_stream = open(out_file, "w") arrival_log = open("arrival.log", "w") # listen to messages while True: message = recv_socket.recvfrom(2048)[0] if message: message_packet = packet.parse_udp_data(message) arrival_log.write("{}\n".format(message_packet.seq_num)) ack_packet = None if message_packet.seq_num == expected_seq_num: done_first_packet = True cur_packet_seq_num = expected_seq_num if message_packet.type == 1: out_file_stream.write(message_packet.data) expected_seq_num = (expected_seq_num + 1) % packet.SEQ_NUM_MODULO elif not done_first_packet: continue
# command line hostAddress = sys.argv[1] sendAckPort = int(sys.argv[2]) receiveDataPort = int(sys.argv[3]) filename = sys.argv[4] serverSocket = socket(AF_INET, SOCK_DGRAM) serverSocket.bind(('', receiveDataPort)) expectingPacket = 0 f = open(filename, "w") while True: UDPdata, clientAddress = serverSocket.recvfrom( 2048 ) p = packet.parse_udp_data(UDPdata) returnPacket = None # if data if p.type == 1: if p.seq_num == expectingPacket % packet.SEQ_NUM_MODULO: f.write(p.data) # read and write to file expectingPacket = expectingPacket + 1 returnPacket = packet.create_ack( expectingPacket % packet.SEQ_NUM_MODULO - 1) # send if not expectingPacket == 0: # if received atleast one good packet serverSocket.sendto( returnPacket.get_udp_data() , (hostAddress, sendAckPort)) # if eot elif p.type == 2: