diff --git a/server.py b/server.py index 542937b..36b6234 100644 --- a/server.py +++ b/server.py @@ -1,6 +1,6 @@ import socket, struct, os, select, math, hashlib, re#, brotli -max_frame_payload=508 +max_frame_payload=1016 #508 is the minimum size for routers to "understand" udp packets, but we can possibly send more data header = "!L16s" header_size = struct.calcsize(header) max_payload = max_frame_payload - header_size @@ -16,9 +16,23 @@ UDPServerSocket.bind((localip, localport)) print("UDP server up and listening") -packet_request_format = re.compile("[a-zA-Z0-9.-_ ]+/[0-9]+") +packet_request_format = re.compile("([a-zA-Z0-9.-_ ]+)(/[0-9]+)+") hash_request_format = re.compile("[a-zA-Z0-9.-_ ]+:") +def send_missing_packet(filename, address, msgpart): + with open(filename, 'rb') as f: + #part = int(message.decode().split('/')[1]) + part = int(msgpart) + #print(f'part {part} | msgpart {msgpart}') + f.seek(part*max_payload) + data = f.read(max_payload) + + #data = deflate.gzip_compress(data, 12) + + checksum = hashlib.sha3_512(data).digest()[:16] + data = struct.pack(f"{header}{max_payload}s", part, checksum, data) + UDPServerSocket.sendto(data, address) + while True: ready = select.select([UDPServerSocket], [], [], 0.1) @@ -40,14 +54,10 @@ while True: filename = "./files/"+message.decode().split('/')[0] if not os.path.isfile(filename): continue - with open(filename, 'rb') as f: - part = int(message.decode().split('/')[1]) - f.seek(part*max_payload) - data = f.read(max_payload) - checksum = hashlib.sha3_512(data).digest()[:16] - data = struct.pack(f"{header}{max_payload}s", part, checksum, data) - UDPServerSocket.sendto(data, address) - print(f'sent lost packet {message.decode()}') + + for msgpart in message.decode().split('/')[1:]: + send_missing_packet(filename, address, msgpart) #extracted from loop for clarity + print(f'sent lost packets {message.decode()}') continue if re.match(hash_request_format, message.decode()): @@ -59,7 +69,7 @@ while True: with open(filename, 'rb') as f: data = f.read(max_payload) sha512.update(data) - UDPServerSocket.sendto(struct.pack("64s", sha512.digest()), address) + UDPServerSocket.sendto(struct.pack("64sx", sha512.digest()), address) continue filename = "./files/"+message.decode() @@ -72,7 +82,7 @@ while True: if last_packet_size == 0: last_packet_size = max_payload # if last packet is full, set size to max #print(max_payload,last_packet_size) - + filename_checksum = sum(message) tosend = struct.pack(f'!IHQ', file_len, last_packet_size, filename_checksum) @@ -86,14 +96,15 @@ while True: for i in range(file_len): fdata = f.read(max_payload) sha512.update(fdata) - #if i == 5: #simulate lost packet - # continue - checksum = hashlib.sha3_512(fdata).digest()[:16] - data = struct.pack(f"{header}{max_payload}s", i, checksum, fdata) + if i == 5: #simulate lost packet + continue + + checkhash = hashlib.sha3_512(fdata).digest()[:16] + data = struct.pack(f"{header}{max_payload}s", i, checkhash, fdata) #print("sending data",fdata) UDPServerSocket.sendto(data, address) print(f'{i+1}/{file_len}', end='\r') - UDPServerSocket.sendto(struct.pack("64s", sha512.digest()), address) + UDPServerSocket.sendto(struct.pack("64sx", sha512.digest()), address) except: pass print(' '*100,end='\r') \ No newline at end of file