I am trying to write a Python program using a client-server model that supports uploading a file from client to server by fragmenting the file and for each fragment, create a thread to send it.
I try to fragment the file into 32 KB chunks.
def __init__(self, host, port, threads=5):
self.host = host
self.port = port
self.fragment_size = 1024 * 32
self.threads = threads
def upload_file(self):
file_name = filedialog.askopenfilename(title="Select file to upload")
if file_name:
with ThreadPoolExecutor(max_workers=self.threads) as executor:
executor.submit(self.send_file, file_name)
def send_file(self, filename):
try:
file_size = os.path.getsize(filename)
fragment_count = (file_size // self.fragment_size) + (1 if file_size % self.fragment_size != 0 else 0)
if not self.send_metadata(filename, file_size, fragment_count):
raise Exception("Failed to send metadata.")
with open(filename, 'rb') as file:
with ThreadPoolExecutor(max_workers=self.threads) as executor:
futures = []
for fragment_number in range(fragment_count):
fragment = file.read(self.fragment_size)
futures.append(executor.submit(self.send_fragment, fragment, fragment_number, fragment_count))
for future in futures:
future.result()
except Exception as e:
messagebox.showerror("Error", f"Failed to upload file: {e}")
And for each send_fragment thread, I create a new socket:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
client_socket.connect((self.host, self.port))
The code seems to work correctly with small files, but when it comes to large files (larger than 500MB), this error occurs:
[WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted.
The requirement of this program is to fragment the file and create a thread to send each fragment.
SO_REUSEADDRon a TCP client socket, especially when you are not explicitlybind()'ing it. That socket option is more useful for listening server sockets instead