init
This commit is contained in:
commit
320ad23b29
129
client.py
Normal file
129
client.py
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
timeout = 1
|
||||||
|
serverAddressPort = ("213.47.107.152", 1337)
|
||||||
|
|
||||||
|
possible_value = input("Enter a value: ")
|
||||||
|
filename = possible_value if (filename := possible_value) else "data.bin"
|
||||||
|
|
||||||
|
import socket, struct, select, time, math
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
#import brotli #pip install brotlipy
|
||||||
|
|
||||||
|
max_frame_payload=508
|
||||||
|
header = "!L16s"
|
||||||
|
header_size = struct.calcsize(header)
|
||||||
|
max_payload = max_frame_payload - header_size
|
||||||
|
|
||||||
|
UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
|
||||||
|
|
||||||
|
|
||||||
|
message = filename
|
||||||
|
|
||||||
|
|
||||||
|
UDPClientSocket.sendto(str.encode(message), serverAddressPort)
|
||||||
|
|
||||||
|
msgFromServer = UDPClientSocket.recvfrom(max_frame_payload)[0]
|
||||||
|
|
||||||
|
msg = struct.unpack(f'!LH{len(message)}s', msgFromServer)
|
||||||
|
|
||||||
|
last_packet_size = msg[1]
|
||||||
|
|
||||||
|
if msg[2] != str.encode(message):
|
||||||
|
print('Server error: wrong file name')
|
||||||
|
exit()
|
||||||
|
|
||||||
|
total_packets = msg[0]
|
||||||
|
|
||||||
|
packets = msg[0]
|
||||||
|
|
||||||
|
print(f'Packets to receive: {packets}')
|
||||||
|
|
||||||
|
total_data = b''
|
||||||
|
|
||||||
|
data_packets = []
|
||||||
|
for i in range(packets):
|
||||||
|
data_packets.append(None)
|
||||||
|
|
||||||
|
sha512 = hashlib.sha512()
|
||||||
|
|
||||||
|
serverhash = None
|
||||||
|
|
||||||
|
time_started = time.time()
|
||||||
|
|
||||||
|
while packets > 0 or serverhash == None:
|
||||||
|
|
||||||
|
ready = select.select([UDPClientSocket], [], [], timeout)
|
||||||
|
|
||||||
|
if ready[0]:
|
||||||
|
|
||||||
|
datareceived = UDPClientSocket.recvfrom(max_frame_payload)[0]
|
||||||
|
if len(datareceived) == 64:
|
||||||
|
serverhash = struct.unpack("64s", datareceived)[0]
|
||||||
|
continue
|
||||||
|
if len(datareceived) != max_frame_payload:
|
||||||
|
print("\nerror bad packet: wrong size",len(datareceived))
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
seq,checksum,data = struct.unpack(f"{header}{max_payload}s", datareceived)
|
||||||
|
if data_packets[seq] != None:
|
||||||
|
print("\nerror bad packet: received multiple times",seq)
|
||||||
|
continue
|
||||||
|
|
||||||
|
#check if packet is last packet and cut data to last packet size
|
||||||
|
if seq == total_packets-1:
|
||||||
|
#print("len before cut",len(data))
|
||||||
|
data = data[:last_packet_size]
|
||||||
|
# print("len after cut",len(data))
|
||||||
|
|
||||||
|
#check if packet is corrupted
|
||||||
|
if checksum.hex() != hashlib.sha3_512(data).digest()[:16].hex():
|
||||||
|
print("\nerror bad packet: checksum mismatch",seq)
|
||||||
|
print(checksum.hex(),hashlib.sha3_512(data).digest()[:16].hex())
|
||||||
|
print(data.hex())
|
||||||
|
continue
|
||||||
|
|
||||||
|
data_packets[seq] = data
|
||||||
|
|
||||||
|
packets -= 1
|
||||||
|
else:
|
||||||
|
#collect packets that were not received and send them in one message
|
||||||
|
for i in range(len(data_packets)):
|
||||||
|
if data_packets[i] == None:
|
||||||
|
#print("requesting packet", i)
|
||||||
|
UDPClientSocket.sendto(str.encode(f"{message}/{i}"), serverAddressPort)
|
||||||
|
|
||||||
|
if serverhash == None:
|
||||||
|
UDPClientSocket.sendto(str.encode(f"{message}:"), serverAddressPort)
|
||||||
|
print(f'{total_packets - packets}/{total_packets} | {math.floor((total_packets - packets)/(time.time()-time_started if (time.time()-time_started)!=0 else 1)*max_payload)}Bps'+'\t'*10, end='\r')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("finished transfer", end='\r')
|
||||||
|
|
||||||
|
for packet in data_packets:
|
||||||
|
sha512.update(packet)
|
||||||
|
|
||||||
|
sha512 = sha512.hexdigest()
|
||||||
|
|
||||||
|
print('sha512: %s' % sha512)
|
||||||
|
|
||||||
|
print('server sha512: %s' % serverhash.hex())
|
||||||
|
|
||||||
|
if sha512 != serverhash.hex():
|
||||||
|
print('hash mismatch')
|
||||||
|
with open("received/"+filename+".corrupt", 'wb') as f:
|
||||||
|
f.write(total_data)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
total_data = b''.join(data_packets)
|
||||||
|
|
||||||
|
with open("received/"+filename, 'wb') as f:
|
||||||
|
f.write(total_data)
|
||||||
|
|
||||||
|
print(f'{filename} generated with size {len(total_data)} bytes')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
9
generate_data.py
Normal file
9
generate_data.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import secrets
|
||||||
|
|
||||||
|
rndsize = 488*50_000
|
||||||
|
|
||||||
|
rndbytes = secrets.token_bytes(rndsize)
|
||||||
|
|
||||||
|
open('files/data.bin', 'wb').write(rndbytes)
|
||||||
|
|
||||||
|
print('data.bin generated with size %d bytes' % rndsize)
|
92
server.py
Normal file
92
server.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import socket, struct, os, select, math, hashlib, re#, brotli
|
||||||
|
|
||||||
|
max_frame_payload=508
|
||||||
|
header = "!L16s"
|
||||||
|
header_size = struct.calcsize(header)
|
||||||
|
max_payload = max_frame_payload - header_size
|
||||||
|
|
||||||
|
localport = 1337
|
||||||
|
localip = '0.0.0.0'
|
||||||
|
|
||||||
|
|
||||||
|
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
|
||||||
|
|
||||||
|
UDPServerSocket.bind((localip, localport))
|
||||||
|
UDPServerSocket.setblocking(0)
|
||||||
|
|
||||||
|
print("UDP server up and listening")
|
||||||
|
|
||||||
|
packet_request_format = re.compile("[a-zA-Z0-9.-_ ]+/[0-9]+")
|
||||||
|
hash_request_format = re.compile("[a-zA-Z0-9.-_ ]+:")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
ready = select.select([UDPServerSocket], [], [], 0.1)
|
||||||
|
|
||||||
|
if ready[0]:
|
||||||
|
|
||||||
|
bytesAddressPair = UDPServerSocket.recvfrom(max_frame_payload)
|
||||||
|
|
||||||
|
message = bytesAddressPair[0]
|
||||||
|
|
||||||
|
if ".." in message.decode():
|
||||||
|
continue
|
||||||
|
|
||||||
|
address = bytesAddressPair[1]
|
||||||
|
|
||||||
|
if re.match(packet_request_format, message.decode()):
|
||||||
|
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()}')
|
||||||
|
continue
|
||||||
|
|
||||||
|
if re.match(hash_request_format, message.decode()):
|
||||||
|
print("hash request")
|
||||||
|
filename = "./files/"+message.decode().split(':')[0]
|
||||||
|
if not os.path.isfile(filename):
|
||||||
|
continue
|
||||||
|
sha512 = hashlib.sha1()
|
||||||
|
with open(filename, 'rb') as f:
|
||||||
|
data = f.read(max_payload)
|
||||||
|
sha512.update(data)
|
||||||
|
UDPServerSocket.sendto(struct.pack("64s", sha512.digest()), address)
|
||||||
|
continue
|
||||||
|
|
||||||
|
filename = "./files/"+message.decode()
|
||||||
|
if not os.path.isfile(filename):
|
||||||
|
continue
|
||||||
|
file_len = math.ceil(os.path.getsize(filename)/max_payload)
|
||||||
|
|
||||||
|
#calculate last packet size
|
||||||
|
last_packet_size = os.path.getsize(filename) % max_payload
|
||||||
|
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)
|
||||||
|
|
||||||
|
tosend = struct.pack(f'!LH{len(message.decode())}s', file_len, last_packet_size, message)
|
||||||
|
|
||||||
|
UDPServerSocket.sendto(tosend, address)
|
||||||
|
|
||||||
|
sha512 = hashlib.sha512()
|
||||||
|
|
||||||
|
with open(filename, 'rb') as f:
|
||||||
|
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)
|
||||||
|
#print("sending data",fdata)
|
||||||
|
UDPServerSocket.sendto(data, address)
|
||||||
|
print(f'{i+1}/{file_len}', end='\r')
|
||||||
|
UDPServerSocket.sendto(struct.pack("64s", sha512.digest()), address)
|
||||||
|
print(' '*100,end='\r')
|
Loading…
x
Reference in New Issue
Block a user