如何停止pyftpdlib FTP服务器?

2 投票
3 回答
4330 浏览
提问于 2025-04-30 01:34

我刚开始学习使用pyftpdlib。首先我想做的是把示例服务器放到一个线程里。但是如果我这样运行,脚本就是不会退出:

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
import logging

import threading

class FtpThread(threading.Thread):
  def __init__(self, user_list):
    self.user_list = user_list
    self.killswitch = 0
    threading.Thread.__init__(self)
  def run(self,*args,**kwargs):
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', 'bla', '/home/user/git/verteilerCore2/default_basedir/in/1/', perm='elradfmwM')
    handler = FTPHandler
    handler.authorizer = authorizer

    logging.basicConfig(filename='/var/log/verteiler_ftp.log', level=logging.INFO)
    handler.banner = "pyftpdlib based ftpd ready."
    address = ('', 21)
    self.server = FTPServer(address, handler)
    self.server.max_cons = 256
    self.server.max_cons_per_ip = 5
    self.server.serve_forever()

  def stop(self):
    self.server.close_all()

def main():
  ftp_server = FtpThread("")
  ftp_server.start()
  import time
  time.sleep(1)
  ftp_server.stop()

if __name__ == '__main__':
    main()

我需要做些什么才能让server_forever停止呢?调用“close_all”可以让服务器停止服务,但整个脚本就是不退出 :(

暂无标签

3 个回答

0

我找到了这个解决方案。在Windows 10和Linux(Windows 10的WSL)上测试过。

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import ThreadedFTPServer
import os


class MyFTPHandler(FTPHandler):
    def on_file_received(self, file):
        if os.path.basename(file) == 'last_file':
            self.server.close_when_done()


def main():
    authorizer = DummyAuthorizer()
    authorizer.add_anonymous('/mnt/c/Temp/ftp' if os.name == 'posix' else r'C:\Temp\ftp', perm='w')

    handler = MyFTPHandler
    handler.authorizer = authorizer

    server = ThreadedFTPServer(('0.0.0.0', 21), handler)
    server.serve_forever()


if __name__ == '__main__':
    main()
0

我在Windows 8上试过这个,结果是正常退出的:

[I 14-10-28 11:49:18] >>> starting FTP server on :::21, pid=1892 <<<
[I 14-10-28 11:49:18] poller: <class 'pyftpdlib.ioloop.Select'>
[I 14-10-28 11:49:18] masquerade (NAT) address: None
[I 14-10-28 11:49:18] passive ports: None
[I 14-10-28 11:49:19] >>> shutting down FTP server (0 active fds) <<<

你能提供更多关于你设置的细节吗?

2

我遇到了同样的问题(python 2.7.14,Ubuntu 16.04)。根据这个链接的建议 https://github.com/giampaolo/pyftpdlib/blob/master/pyftpdlib/test/test_servers.py,我通过使用 ThreadedFTPServer 代替 FTPServer 解决了这个问题。

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import ThreadedFTPServer

import threading

def __init__(self, addr):
    authorizer = DummyAuthorizer()
    authorizer.add_anonymous(os.getcwd())

    handler = FTPHandler
    handler.authorizer = authorizer
    handler.banner = "pyftpdlib based ftpd ready."

    ThreadedFTPServer.__init__(self, addr, handler)

    # set a limit for connections
    self.max_cons = 256
    self.max_cons_per_ip = 5

def _run_server(self):
    self.serve_forever()

def start(self):
    srv = threading.Thread(target=self._run_server)
    srv.deamon = True
    srv.start()

def stop(self):
    self.close_all()

--> 在这种情况下,调用 "close_all" 会让脚本退出

撰写回答