support multi-lost packet request

clearer code
This commit is contained in:
Mystikfluu 2023-05-22 23:00:04 +02:00
parent f96cb16268
commit e997a4fc58

View File

@ -1,6 +1,6 @@
import socket, struct, os, select, math, hashlib, re#, brotli 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 = "!L16s"
header_size = struct.calcsize(header) header_size = struct.calcsize(header)
max_payload = max_frame_payload - header_size max_payload = max_frame_payload - header_size
@ -16,9 +16,23 @@ UDPServerSocket.bind((localip, localport))
print("UDP server up and listening") 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.-_ ]+:") 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: while True:
ready = select.select([UDPServerSocket], [], [], 0.1) ready = select.select([UDPServerSocket], [], [], 0.1)
@ -40,14 +54,10 @@ while True:
filename = "./files/"+message.decode().split('/')[0] filename = "./files/"+message.decode().split('/')[0]
if not os.path.isfile(filename): if not os.path.isfile(filename):
continue continue
with open(filename, 'rb') as f:
part = int(message.decode().split('/')[1]) for msgpart in message.decode().split('/')[1:]:
f.seek(part*max_payload) send_missing_packet(filename, address, msgpart) #extracted from loop for clarity
data = f.read(max_payload) print(f'sent lost packets {message.decode()}')
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()}')
continue continue
if re.match(hash_request_format, message.decode()): if re.match(hash_request_format, message.decode()):
@ -59,7 +69,7 @@ while True:
with open(filename, 'rb') as f: with open(filename, 'rb') as f:
data = f.read(max_payload) data = f.read(max_payload)
sha512.update(data) sha512.update(data)
UDPServerSocket.sendto(struct.pack("64s", sha512.digest()), address) UDPServerSocket.sendto(struct.pack("64sx", sha512.digest()), address)
continue continue
filename = "./files/"+message.decode() filename = "./files/"+message.decode()
@ -72,7 +82,7 @@ while True:
if last_packet_size == 0: if last_packet_size == 0:
last_packet_size = max_payload # if last packet is full, set size to max last_packet_size = max_payload # if last packet is full, set size to max
#print(max_payload,last_packet_size) #print(max_payload,last_packet_size)
filename_checksum = sum(message) filename_checksum = sum(message)
tosend = struct.pack(f'!IHQ', file_len, last_packet_size, filename_checksum) tosend = struct.pack(f'!IHQ', file_len, last_packet_size, filename_checksum)
@ -86,14 +96,15 @@ while True:
for i in range(file_len): for i in range(file_len):
fdata = f.read(max_payload) fdata = f.read(max_payload)
sha512.update(fdata) sha512.update(fdata)
#if i == 5: #simulate lost packet if i == 5: #simulate lost packet
# continue continue
checksum = hashlib.sha3_512(fdata).digest()[:16]
data = struct.pack(f"{header}{max_payload}s", i, checksum, fdata) checkhash = hashlib.sha3_512(fdata).digest()[:16]
data = struct.pack(f"{header}{max_payload}s", i, checkhash, fdata)
#print("sending data",fdata) #print("sending data",fdata)
UDPServerSocket.sendto(data, address) UDPServerSocket.sendto(data, address)
print(f'{i+1}/{file_len}', end='\r') 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: except:
pass pass
print(' '*100,end='\r') print(' '*100,end='\r')