The code is too non-minimal so here's a minimal example of downloading an unencrypted file. Also, TCP is a streaming protocol and using sleeps to separate your data is incorrect. Define a protocol for the byte stream instead. This is the protocol of my example:
- Open the connection.
- Send the UTF-8-encoded filename followed by a newline.
- Send the encoded file size in decimal followed by a newline.
- Send the file bytes.
- Close the connection.
Note Python 3 code. Python 2 is dead to me. Support ends next year for it so upgrade!
server.py
from socket import *
import os
CHUNKSIZE = 1_000_000
# Make a directory for the received files.
os.makedirs('Downloads',exist_ok=True)
sock = socket()
sock.bind(('',5000))
sock.listen(1)
with sock:
while True:
client,addr = sock.accept()
# Use a socket.makefile() object to treat the socket as a file.
# Then, readline() can be used to read the newline-terminated metadata.
with client, client.makefile('rb') as clientfile:
filename = clientfile.readline().strip().decode()
length = int(clientfile.readline())
print(f'Downloading {filename}:{length}...')
path = os.path.join('Downloads',filename)
# Read the data in chunks so it can handle large files.
with open(path,'wb') as f:
while length:
chunk = min(length,CHUNKSIZE)
data = clientfile.read(chunk)
if not data: break # socket closed
f.write(data)
length -= len(data)
if length != 0:
print('Invalid download.')
else:
print('Done.')
client.py
from socket import *
import os
CHUNKSIZE = 1_000_000
filename = input('File to upload: ')
sock = socket()
sock.connect(('localhost',5000))
with sock,open(filename,'rb') as f:
sock.sendall(filename.encode() + b'
')
sock.sendall(f'{os.path.getsize(filename)}'.encode() + b'
')
# Send the file in chunks so large files can be handled.
while True:
data = f.read(CHUNKSIZE)
if not data: break
sock.sendall(data)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…