-
- Notifications
You must be signed in to change notification settings - Fork 277
Open
Description
I have a requirement where the server should be able to detect whether the file uploaded by the client is fully received or not. To simulate this process, I have uploaded multiple files (of size >150mb) to the server and intentionally closed the connection in the middle of the upload. The callback did work sometimes but it missed in as many times. I don't know the reason, but I think of it as an issue with the library itself. I'm sharing the server and client code for reference.
##Client Script##
import ftplib import os from PyQt5 import QtCore, QtWidgets from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QProgressBar, QPushButton, QVBoxLayout, QWidget class FTPClient: def __init__(self, host, port, username, password): self.host = host self.port = port self.username = username self.password = password self.ftp = None def connect(self): try: self.ftp = ftplib.FTP() self.ftp.connect(self.host, self.port) self.ftp.login(self.username, self.password) print(f"Connected to {self.host}:{self.port}") except ftplib.all_errors as e: print(f"Error connecting to FTP server: {e}") return False return True def upload_file(self, file_paths, progress_callback): try: for file_path in file_paths: file_size = os.path.getsize(file_path) with open(file_path, 'rb') as file: def handle_progress(block): progress_callback(file.tell(), file_size) try: self.ftp.storbinary(f'STOR {os.path.basename(file_path)}', file, 1024, callback=handle_progress) print(f'File {file_path} uploaded successfully.') except (ftplib.error_temp, ftplib.error_perm) as e: print(f'Error during file upload: {e}') continue # Continue with the next file except ftplib.all_errors as e: print(f'Error uploading file: {e}') def close(self): if self.ftp: self.ftp.quit() class FTPClientApp(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("FTP Client") self.setGeometry(100, 100, 400, 200) self.ftp_client = None self.progress_bar = QProgressBar(self) self.progress_bar.setGeometry(50, 50, 300, 30) self.upload_button = QPushButton("Upload File", self) self.upload_button.setGeometry(150, 100, 100, 40) self.upload_button.clicked.connect(self.upload_file) def upload_file(self): file_path, _ = QFileDialog.getOpenFileNames(self, "Select Files to Upload") if file_path: self.progress_bar.setValue(0) self.ftp_client = FTPClient("localhost", 2121, "user", "12345") if self.ftp_client.connect(): self.upload_button.setEnabled(False) self.ftp_client.upload_file(file_path, self.update_progress) self.upload_button.setEnabled(True) self.ftp_client.close() def update_progress(self, bytes_sent, total_size): progress = (bytes_sent / total_size) * 100 self.progress_bar.setValue(int(progress)) if __name__ == "__main__": app = QApplication([]) window = FTPClientApp() window.show() app.exec_() ##Server Script##
import os from pyftpdlib.handlers import FTPHandler from pyftpdlib.servers import FTPServer from pyftpdlib.authorizers import DummyAuthorizer class MyHandler(FTPHandler): def on_connect(self): print("%s:%s connected" % (self.remote_ip, self.remote_port)) def on_disconnect(self): # do something when client disconnects pass def on_login(self, username): # do something when user login pass def on_logout(self, username): # do something when user logs out pass def on_file_sent(self, file): # do something when a file has been sent pass def on_file_received(self, file): # do something when a file has been received pass def on_incomplete_file_sent(self, file): # do something when a file is partially sent pass def on_incomplete_file_received(self, file): # remove partially uploaded files print(f"File incompletely shared: {file}") import os os.remove(file) def main(): homedir = os.path.dirname(os.path.abspath(__file__)) print(homedir) authorizer = DummyAuthorizer() authorizer.add_user('user', '1234asff5', homedir=homedir, perm='elradfmwMT') authorizer.add_anonymous(homedir=homedir) handler = MyHandler handler.authorizer = authorizer server = FTPServer(('', 2121), handler) server.serve_forever() Metadata
Metadata
Assignees
Labels
No labels