[PyQt] [solved] Re: problem with threaded ftp and QFtp.close()

Brian Knudson briank at pipelinefx.com
Tue Mar 19 17:05:53 GMT 2013

On Mar 19, 2013, at 2:24 AM, Phil Thompson wrote:

> On Mon, 18 Mar 2013 19:42:00 -0700, Brian Knudson <briank at pipelinefx.com>
> wrote:
>> I'm running multiple instances of QFtp in multiple QThreads so I can
>> download in multiple streams at the same time.
>> If I leave out ftp.close() (where ftp is a QFtp), all my threads
> properly
>> emit a finished signal.  This is great, but it leaves the ftp user
> logged
>> into my ftp server, eventually hitting a max_connections limit (on the
> ftp
>> server), which prevents the remaining ftp transfers from starting.  When
>> the program exits, the connections do close.
>> If I follow my ftp.get(...) (there is one per thread) with an
> ftp.close(),
>> I can see the connections closing on my ftp server, I never hit
>> max_connections on the ftp server, every download completes, but the
>> threads never emit a "finished" signal (likely because the QFtp never
> emits
>> a "done" signal), so the rest of the application doesn't behave
> properly.
>> I haven't made an example, as an example would require a fair amount of
>> effort.  I'm wondering if anyone else has seen this or would have an
> idea
>> of special handling required for the .close() method of QFtps in
> threads.
>> Maybe it using ftp.close() implies a "done" signal & one must be
> manually
>> emitted by catching the close in the ftp.commandFinished signal handler?
>> At the end of the day, the QThread's run method looks something like:
>> self.ftp = QtNetwork.QFtp()
>> self.ftp.commandFinished.connect(self.ftpCommandFinished)
>> self.ftp.dataTransferProgress.connect(self.ftpDataTransferProgress)
>> self.ftp.connectToHost(url.host(), url.port(21))
>> self.ftp.login(url.userName(), url.password())
>> self.ftp.get(url.path(), self.out_file)
>> self.ftp.close()
> QFtp is an asynchronous implementation so you don't need QThreads to
> download multiple streams at the same time.

Fair enough. At the end of the day, I had created a throttle-able threading mechanism for another part of the app, so I re-used it for ftp.  Personally, I find threads easier to use/understand than asynchronous ftp execution - maybe that's just me.  

For the googlers, I solved this by setting up a slot for stateChanged & check if the state is QFtp.Closing or QFtp.Unconnected.  In either case, I call the same slot that the "done" signal uses which then tells my app to check md5s & such.  All is working now.  If there is something wrong with this approach, please let me know.


More information about the PyQt mailing list