Essays
Topics
Writing Tool
Machine Learning AI
ChatGPT
US History
Presidents of the United States
Joseph Robinette Biden
Donald Trump
Barack Obama
US States
States Ranked by Size & Population
States Ranked by Date
IPL
>
Electrical Engineering
>
UDP Packet Sender: Efficient File Transmission in Python
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 socket
import time
from sys import argv
from packet import Packet
from 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 socket
sender_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sender_socket.bind(('', ack_port))
sender_socket.settimeout(0)
window_size = 5
seqnum = 0
unacked_packets = []
packets = {} # dict for seqno and packet
timer = None
# read all contents of file and store in packets dict
with 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] = packet
seqnum += 1
print("num packets read: ", len(packets))
# reset seqnum
seqnum = 0
while True:
# send eot packet to receiver
if 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 yet
if timer == None:
timer = time.time()
# timeout
if 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 = 5
else: # increase window size by 1 or to max window size
window_size = min(window_size + 1, max_window_size)
# check for acks
ack = None
try:
ack, _ = sender_socket.recvfrom(2048)
except BlockingIOError:
pass
if ack == None:
print("no ack received")
continue
packet_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 = None
else:
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)
#
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:
#
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)