This question is the follow up from a previous question I asked. I have incorporated the code that resolves that issue. My program uses threading and SSL. I am still unsure if this is relevant, so I decided to post a complete working sample of both the server and client, in the hope that someone may be able to assist in working out why I cannot send large files.
When I uncomment line 9 in client.py (FILENAME = '2KB.zip'; this is actually a 1.5KB zip file), everything works as expected. The md5sum of the file on the server side matches the one on the client side.
However, when I run the code as is, attempting to send the '44MB.zip' file (which is indeed a 44MB zip file), there is always a (different) remaining amount of bytes and it ends with a ConnectionResetError: [Errno 104] Connection reset by peer. Any insights into why this happens and what I can do to resolve the issue are greatly appreciated.
Here is what the output looks like when sending 44MB.zip:
...
Remaining: 505927
Remaining: 495687
Remaining: 485447
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "gen3-server.py", line 25, in handle_client
count = f.write(r.read(min(10240, remaining)))
File "/usr/lib/python3.8/socket.py", line 669, in readinto
return self._sock.recv_into(b)
File "/usr/lib/python3.8/ssl.py", line 1241, in recv_into
return self.read(nbytes, buffer)
File "/usr/lib/python3.8/ssl.py", line 1099, in read
return self._sslobj.read(len, buffer)
ConnectionResetError: [Errno 104] Connection reset by peer
# server.py
import socket
import ssl
import threading
import os
import json
server_ip = "192.168.12.110"
server_port = 443
server_address = (server_ip, server_port)
def handle_client(conn, addr):
r = conn.makefile('rb')
with conn, r:
while True:
header_line = r.readline()
if not header_line: break
header = json.loads(header_line)
print('Header received from client: ' + str(header))
remaining = header['length']
with open(header['filename'], 'wb') as f:
while remaining:
count = f.write(r.read(min(10240, remaining)))
print('Remaining: ' + str(remaining))
if not count:
if remaining:
break
remaining -= count
else:
return
return
def main():
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain('/etc/ssl/certs/server-certificate.pem', keyfile='/etc/ssl/private/server-private-key.pem', password='password')
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(server_address)
server.listen()
server = context.wrap_socket(server, server_side=True)
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
if __name__ == "__main__":
main()
# client.py
import socket
import ssl
import json
server_ip = "192.168.12.110"
server_port = 443
server_address = (server_ip, server_port)
FILENAME = '44MB.zip'
#FILENAME = '2KB.zip'
def transmit(sock, filename, author, content):
msg = {'filename': filename, 'author': author, 'length': len(content)}
data = json.dumps(msg, ensure_ascii=False).encode() + b'\r\n' + content
sock.sendall(data)
def main():
context = ssl.SSLContext()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_verify_locations(cafile='ca-certificate.pem')
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client = context.wrap_socket(client, server_hostname="ag-docose1")
client.connect(server_address)
with client:
with open(FILENAME, 'rb') as f:
content = f.read()
transmit(client, FILENAME, 'Marc', content)
if __name__ == "__main__":
main()