python实现ftp服务器(使用wxpython实现GUI界面)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python实现ftp服务器(使用wxpython实现GUI界面)相关的知识,希望对你有一定的参考价值。
开发背景:
有时需要在局域网传输文件,总是要用U盘传输,要是多个人都需要同样的文件,U盘就有点麻烦了,Windows上的文件共享配置步骤很少,但是经常因为各种原因失败,又要检查来检查去的。于是考虑到通过FTP协议来传输文件,但是出名的FTP服务器软件类似Serv-U 这种,功能是很强大,但是配置也很多,我只是临时传输下文件,希望可以免安装,一键启动FTP,一键关闭FTP。于是就想使用python实现FTP服务器,再打包成exe文件。
开发环境:
win 7 64位,Python 3.6.2,pyftpdlib,wxpython,pyinstaller 3.3.1
具体思路:
通过pyftpdlib库实现FTP 功能ftpserver.py,使用wxpython实现GUI界面wxgui.py,在wxgui.py上生成配置文件config.ini,ftpserver.py再获取config.ini中的信息启动FTP,最后使用pyinstaller打包成exe可执行文件。
软件截图:
不过刚开发好的软件,应该有挺多BUG的,以后使用过程中再慢慢改进。
打开软件:
选择FTP目录:
启动FTP:
具体源代码:
实现FTP功能代码ftpserver.py:
# coding:utf-8
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
import logging
import configparser
import os
def ftpd():
authorizer = DummyAuthorizer()
if getconfig(‘anonymous‘)==‘True‘:
#添加匿名用户
authorizer.add_anonymous(getconfig(‘dir‘),perm=‘elradfmwM‘)
else:
#添加用户,需要账号和密码登录
authorizer.add_user(getconfig(‘user‘), getconfig(‘password‘), getconfig(‘dir‘), perm=‘elradfmwM‘)
handler = FTPHandler#初始化处理客户端命令的类
handler.authorizer = authorizer#选择登录方式(是否匿名)
logging.basicConfig(filename=‘ftpd.log‘, level=logging.INFO) #日志信息写入ftpd.log
address = (‘0.0.0.0‘, getconfig(‘port‘))#设置服务器的监听地址和端口
server = FTPServer(address, handler)
server.max_cons = 256 #给链接设置限制
server.max_cons_per_ip = 5
server.serve_forever() # 启动FTP
def getconfig(v):
#获取config.ini配置文件的信息
config = configparser.ConfigParser()
config.read(‘config.ini‘)
return config.get(‘ftpd‘,v)
if __name__ == ‘__main__‘:
ftpd()
实现GUI界面代码wxgui.py:
# -*- coding:utf-8 -*-
import wx
import os
import sys
import configparser
import ftpserver
import time
import threading
import socket
def onclick(event): #选择FTP目录
dlg=wx.DirDialog(window,‘选择共享目录‘)
if dlg.ShowModal() == wx.ID_OK:
dirtext.SetValue(dlg.GetPath())
def onclose(event): #退出事件
if startbutton.GetLabel()==‘关闭FTP‘:
dlg1 = wx.MessageDialog(None, "FTP正在运行,确认退出吗?", "退出", wx.YES_NO | wx.ICON_EXCLAMATION)
if dlg1.ShowModal()==wx.ID_YES:
sys.exit()
else:
sys.exit()
def startftp(event): #点击 启动FTP 按钮事件
global t
if startbutton.GetLabel()==‘启动FTP‘:
startbutton.SetLabel(‘关闭FTP‘)
#把FTP启动信息写入config.ini配置文件中
config=configparser.ConfigParser()
config.add_section(‘ftpd‘)
config.set(‘ftpd‘,‘anonymous‘,str(not check.GetValue()))
config.set(‘ftpd‘,‘user‘,usertext.GetValue())
config.set(‘ftpd‘,‘password‘,passtext.GetValue())
config.set(‘ftpd‘,‘port‘,porttext.GetValue())
config.set(‘ftpd‘,‘dir‘,dirtext.GetValue())
with open(‘config.ini‘,‘w‘) as conf:
config.write(conf)
time.sleep(1)
#创建线程启动FTP
t=threading.Thread(target=ftpserver.ftpd)
t.setDaemon(True)
t.start()
iplist=socket.gethostbyname_ex(socket.gethostname())[2]
ftpurl=‘‘
if iplist :
for ip in iplist:
ftpurl+=‘FTP地址:ftp://‘+ip+‘:‘+porttext.GetValue()+‘\n‘
urllabel.SetLabel(ftpurl)
else:
dlg1 = wx.MessageDialog(None, "FTP正在运行,确认退出吗?", "退出", wx.YES_NO | wx.ICON_EXCLAMATION)
if dlg1.ShowModal()==wx.ID_YES:
sys.exit()
def onchecked(event): #复选框事件
usertext.SetEditable(event.IsChecked())
passtext.SetEditable(event.IsChecked())
app = wx.App()#实例化wx.App
#创建顶级窗口,并且窗口不可改变尺寸
window = wx.Frame(None,title = "FTP服务器", size = (390, 260), pos=(400,300),style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)
#绑定退出事件
window.Bind(wx.EVT_CLOSE,onclose)
#创建panel
panel = wx.Panel(window)
font = wx.Font(11, wx.SWISS, wx.NORMAL, wx.NORMAL)
#创建复选框,并绑定事件
check=wx.CheckBox(panel,-1,‘使用账户密码登录‘,pos=(20,20),size=(200,-1))
check.SetFont(font)
window.Bind(wx.EVT_CHECKBOX,onchecked)
#创建静态文本和文本输入框
userlabel = wx.StaticText(panel, label = "用户名:", pos=(35,45))
userlabel.SetFont(font)
usertext = wx.TextCtrl(panel,-1,‘‘,size=(95,20),pos=(90,42),style = wx.TE_READONLY)
passlabel = wx.StaticText(panel, label = "密码:",pos=(195,45))
passlabel.SetFont(font)
passtext = wx.TextCtrl(panel,-1,‘‘,size=(95,20),pos=(235,42),style = wx.TE_PASSWORD)
passtext.SetEditable(False)
dirlabel = wx.StaticText(panel, label = "FTP目录:",pos=(23,72))
dirlabel.SetFont(font)
dirtext = wx.TextCtrl(panel,-1,os.getcwd(),size=(215,20),pos=(88,70),style = wx.TE_READONLY)
#创建按钮,并且绑定按钮事件
button=wx.Button(panel,-1,‘更改‘,pos=(310,70),size=(40,20))
button.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL))
window.Bind(wx.EVT_BUTTON,onclick,button)
portlabel = wx.StaticText(panel, label = "FTP端口:",pos=(23,104))
portlabel.SetFont(font)
porttext = wx.TextCtrl(panel,-1,‘21‘,size=(51,20),pos=(88,102))
startbutton=wx.Button(panel,-1,‘启动FTP‘,pos=(160,130),size=(70,30))
startbutton.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL))
window.Bind(wx.EVT_BUTTON,startftp,startbutton)
#加载配置文件,使程序恢复到退出前的界面
if os.path.isfile(‘config.ini‘):
if ftpserver.getconfig(‘anonymous‘)==‘False‘:
check.SetValue(1)
usertext.SetEditable(1)
passtext.SetEditable(1)
usertext.SetValue(ftpserver.getconfig(‘user‘))
passtext.SetValue(ftpserver.getconfig(‘password‘))
porttext.SetValue(ftpserver.getconfig(‘port‘))
dirtext.SetValue(ftpserver.getconfig(‘dir‘))
urllabel = wx.StaticText(panel, label = "", pos=(80, 170))
urllabel.SetFont(font)
window.Show(True)#窗口可见
app.MainLoop() #主循环,处理事件
使用pyinstaller打包
如果顺利的话,两条命令就可以成功打包了,反正我是没那么顺利的了
pip安装pyinstaller
pip install pyinstaller
开始打包:
pyinstaller -F wxgui.py -w
-F 参数:是生成单个可执行文件
-w参数:因为我的是GUI程序,所以我使用这参数去掉命令行窗口
生成的文件:
问题总结:
这次开发这个小项目中遇到了个问题,百度谷歌都找不到解决的办法。
程序创建个线程去启动FTP服务,当我想要停止FTP服务时,在不退出程序的情况下该如何去停止FTP服务?
以上是关于python实现ftp服务器(使用wxpython实现GUI界面)的主要内容,如果未能解决你的问题,请参考以下文章