UDP Packet Sender: Efficient File Transmission in Python

School
University of Waterloo**We aren't endorsed by this school
Course
CS 456
Subject
Electrical Engineering
Date
Dec 10, 2024
Pages
4
Uploaded by ConstableDugongMaster1078
import socketimport timefrom sys import argvfrom packet import Packetfrom datetime import datetime# def main():def main(emulator_host, emulator_port, ack_port, timeout, max_window_size, file_path):# if len(sys.argv) != 7:# print("Usage: sender.py <emulator_host> <emulator_port> <ack_port> <timeout> <N> <file>")# sys.exit(1)# emulator_host = sys.argv[1]# emulator_port = int(sys.argv[2])# ack_port = int(sys.argv[3])# timeout = int(sys.argv[4])# max_window_size = int(sys.argv[5]) # file_path = sys.argv[6]# set up UDP socketsender_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)sender_socket.bind(('', ack_port))sender_socket.settimeout(0)window_size = 5seqnum = 0unacked_packets = []packets = {} # dict for seqno and packettimer = None# read all contents of file and store in packets dictwith open(file_path, 'rb') as file:file_data = file.read()for i in range(0, len(file_data), 500):data = file_data[i:i+500]packet = Packet(1, seqnum, len(data), data.decode())packets[seqnum] = packetseqnum += 1print("num packets read: ", len(packets))# reset seqnumseqnum = 0while True:# send eot packet to receiverif seqnum == len(packets) and len(unacked_packets):print("Sending EOT packet")eot_packet = Packet(2, 0, 0, "")sender_socket.sendto(eot_packet.encode(), (emulator_host, emulator_port))elif len(unacked_packets) < window_size and seqnum < len(packets):print("Sending packet with seqnum: ", seqnum)cur_packet = packets[seqnum]sender_socket.sendto(cur_packet.encode(), (emulator_host, emulator_port))unacked_packets.append(seqnum)seqnum += 1# set timer if not set yetif timer == None:timer = time.time()
Background image
# timeoutif timer and ((time.time() - timer) * 1_000_000) > timeout * 1000:print("timeout")timer = time.time()if len(unacked_packets):for seq in unacked_packets:sender_socket.sendto(packets[seq].encode(), (emulator_host, emulator_port))window_size = 5else: # increase window size by 1 or to max window sizewindow_size = min(window_size + 1, max_window_size)# check for acksack = Nonetry:ack, _ = sender_socket.recvfrom(2048)except BlockingIOError:passif ack == None:print("no ack received")continuepacket_type, ack_num, packet_length, ack_data = Packet(ack).decode()if packet_type == 0:print("received ack: ", ack_num)if ack_num in unacked_packets:unacked_packets.remove(ack_num)if len(unacked_packets) == 0:timer = Noneelse:timer = time.time()elif packet_type == 2:print("Received EOT ack")sender_socket.close()break# with open(file_path, 'rb') as file:# while True:# # if data = None, this is start of the file reading# if data == None:# print("reading first packet")# data = file.read(500)# print("data read: ", data)# length = len(data) # use this to send to receiver# # then we will enter another loop# elif data == b'': # EOF# if unacked_packets == 0:# print("Sending EOT packet")# timestamp += 1# # send eot packet# eot_packet = Packet(2, seqnum, 0, "")# sender_socket.sendto(eot_packet.encode(), (emulator_host, emulator_port))# break# elif unacked_packets < window_size:# print("Sending packet with seqnum: ", seqnum)
Background image
# packet = Packet(1, seqnum, length, data.decode())# packets[seqnum] = packet # in case we need to resend# sender_socket.sendto(packet.encode(), (emulator_host, emulator_port))# timestamp += 1# unacked_packets += 1# seqnum += 1# data = None# # set timer? timer = datetime.now() if this is the first packet being transmitted# if timer == None:# timer == time.time()# # timeout case. resend lost packet only. # if timer and (time.time() - timer).microseconds > timeout * 1000:# print("timeout")# timestamp += 1# window_size = 5# # resend lost packet# unacked_packet = packets[seqnum - unacked_packets]# sender_socket.sendto(unacked_packet.encode(), (emulator_host, emulator_port))# timer = time.time()# timestamp += 1# ack = None# # print("waiting for ack")# # check if ack was given by receiver# try:# ack, _ = sender_socket.recvfrom(1024)# except BlockingIOError:# pass# if ack == None:# # print("no ack received")# continue# print("received ack")# packet_type, ack_num, packet_length, ack_data = Packet(ack).decode()# # check type = 0# # check that ack_num is within the window# if ack_num > seqnum - unacked_packets and ack_num <= seqnum:# print("ack within window")# packets_acked = 1 + ack_num - (seqnum - unacked_packets)# unacked_packets -= packets_acked# if (window_size < max_window_size):# window_size += 1# if unacked_packets == 0:# timer = None# else:
Background image
# timer = time.time()# # receive EOT ack# eot, _ = sender_socket.recvfrom(1024)# sender_socket.close()# if __name__ == "__main__":# main()if __name__ == "__main__":host, em_p, send_p, timeout, max_window, f = argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]start = datetime.now()main(host, int(em_p), int(send_p), int(timeout), int(max_window), f)print(datetime.now() - start)
Background image