最近做了一个简单的文件传输系统,基于ftp协议,使用python语言开发,虽然python里面已经有ftplib模块,可以很容易的实现ftp服务器。这次我使用的是socket实现client与ftp server之间的通讯和文件传输,client另起一个flask服务器,用于用户在浏览器端的交互。系统实现的功能有:用户登录注册,用户查看ftp服务器端文件和下载上传删除操作,支持多进程、多用户。
一,登录注册
该项目使用的是mongo数据库,其实用户登录注册功能很好实现,没有什么技术细节,这里就略过了。数据库管理代码如下:
import pymongo from pymongo.collection import Collection class DBManager(object): def __init__(self): client = pymongo.MongoClient("mongodb://localhost:27017/") self.db = client["FTPDB"] self.users = self.db['user'] #保存用户登录信息 def saveUserInfo(self,account,password): users = self.users.find() for item in users: accountDB = item['account'] if accountDB == account: return "false" data = [] userInfo = {} userInfo['account'] = account userInfo['password'] = password data.append(userInfo) collection = Collection(self.db,"user") collection.insert(data) return "true" def confirmUserLoginInfo(self,account,password): users = self.users.find() ''' result状态: 1:表示初始状态,即不存在用户 2:表示存在该用户、密码不正确 3:验证成功 ''' result = 1 for item in users: accountDB = item['account'] passwordDB = item['password'] if accountDB == account: if passwordDB == password: result = 3 else: result = 2 return result
前端注册js代码如下:
function register() { account = $("#account").val(); password = $("#password").val(); confirmPassword = $("#confirmPassword").val(); if(account == null || password == null || confirmPassword == null){ alert("请先输入必要信息") return; } if(password != confirmPassword){ alert("密码不一致"); return; } var request = { type:"register", account:account, password:password } sendData("http://localhost:8080/register",request) } //向服务器发送数据 function sendData(url,json) { $.ajax({ url: url, //请求的url地址 dataType: "json", //返回格式为json async: true, //请求是否异步,默认为异步,这也是ajax重要特性 data: json, //参数值 type: "post", //请求方式 success:function(data){ //alert(data) if(data.toString() == "false"){ alert("用户名已存在"); }else{ window.location.href = "http://localhost:8080/index"; } }, error:function (error) { console.log(error); } }); }
二,文件管理(文件查看、删除、上传、下载)
客户端与服务器端约定命令格式,服务器通过解析客户端命令来执行操作。
server.py from socket import * import os,sys import signal import time # 全局变量 HOST = '0.0.0.0' PORT = 8686 ADDR = (HOST,PORT) FILE_PATH = '../serverFiles/' # 处理僵尸进程 signal.signal(signal.SIGCHLD,signal.SIG_IGN) # 服务端功能类 class Server(object): def __init__(self): self.connfd = "" def do_list(self,account): # 获取文件列表 file_list = os.listdir(FILE_PATH+account) if not file_list: self.connfd.send("服务器文件库为空".encode()) return else: self.connfd.send(b"OK") time.sleep(0.1) files = "" for file in file_list: if file[0] != '.' and os.path.isfile(FILE_PATH + account +"/"+ file): files += file + '#' self.connfd.send(files.encode()) def delete(self,accout,fileName): os.remove(FILE_PATH + accout + "/" + fileName) self.connfd.send(b"OK") time.sleep(0.1) def do_get(self,account,filename): try: fd = open(FILE_PATH + account +"/"+ filename,'rb') except IOError: self.connfd.send("文件不存在".encode()) return else: #print("发送OK") self.connfd.send(b'OK') time.sleep(0.1) # 发送文件内容 while True: data = fd.read(1024) if not data: time.sleep(0.1) self.connfd.send(b'##') break #print("正在发送数据") self.connfd.send(data) fd.close() def do_put(self,account,filename): if os.path.exists(FILE_PATH + account +"/"+ filename): self.connfd.send('该文件已存在'.encode()) return fd = open(FILE_PATH + account +"/"+ filename,'wb') self.connfd.send(b'OK') # 接收文件内容 while True: data = self.connfd.recv(1024) if data == b'**': break fd.write(data) fd.close() def socket_tcp(self): s = socket() s.setsockopt(SOL_SOCKET,SO_REUSEADDR,True) s.bind(ADDR) s.listen(5) print("Listen the port 8686...") return s def do_request(self,connfd): self.connfd = connfd while True: data = connfd.recv(1024).decode() datas = data.split(' ') if not data or datas[1] == 'QUIT@#': connfd.close() return elif datas[1] == "LIST@#": #print("list") self.do_list(datas[0]) elif datas[1] == 'GET@#': filename = datas[-1] self.do_get(datas[0],filename) elif datas[1] == 'PUT@#': filename = datas[-1] self.do_put(datas[0],filename) elif datas[1] == 'delete@#': filename = datas[-1] self.delete(datas[0],filename) def run(self): # 创建套接字 s = self.socket_tcp() while True: try: connfd,addr = s.accept() except KeyboardInterrupt: sys.exit("服务器退出") except Exception as e: print(e) continue print("Connect from",addr) # 创建子进程 pid = os.fork() if pid == 0: s.close() self.do_request(connfd) #处理客户端具体请求 os._exit(0) else: connfd.close() if __name__ == "__main__": server = Server() server.run() client.py """ client.py """ import socket import os,sys import time # 服务器地址 ADDR = ("127.0.0.1",8686) FILE_PATH = "./clientFiles/" # 客户端功能类 class Client(object): def __init__(self,account): self.sockfd = "" self.account = account #获得服务器文件列表 def server_list(self): ftpServerFiles = [] self.sockfd.send((self.account+' LIST@# ').encode()) # 等待回复 data = self.sockfd.recv(128).decode() if data == "OK": files = self.sockfd.recv(4096).decode() for file in files.split('#'): #print(file) ftpServerFiles.append(file) else: # 无法完成操作 print(data) ftpServerFiles = ftpServerFiles[:-1] return ftpServerFiles #获得用户文件夹列表 def client_list(self): # 获取文件列表 userFiles = [] file_list = os.listdir(FILE_PATH+self.account+"/") if not file_list: return else: time.sleep(0.1) files = "" for file in file_list: if file[0] != '.' and os.path.isfile(FILE_PATH + self.account + "/" + file): userFiles.append(file) return userFiles #退出 def do_quit(self): self.sockfd.send((self.account+' QUIT@# ').encode()) self.sockfd.close() sys.exit('谢谢使用') #用户下载服务器文件 def do_get(self,filename): self.sockfd.send((self.account+' GET@# '+filename).encode()) data = self.sockfd.recv(128).decode() if data == 'OK': fd = open(FILE_PATH + self.account + "/" + filename,'wb') #复写 while True: data = self.sockfd.recv(1024) if data == b'##': #print("##") break #print("正在写入数据") fd.write(data) fd.close() else: print(data) #用户将文件上传到服务器文件夹 def do_put(self,filename): try: fd = open(FILE_PATH + self.account + "/" + filename,'rb') except IOError: print("文件不存在") return # 获取文件名 filename = filename.split('/')[-1] # else: self.sockfd.send((self.account+' PUT@# '+filename).encode()) data = self.sockfd.recv(128).decode() # 发送文件 if data == 'OK': while True: data = fd.read(1024) if not data: time.sleep(0.1) self.sockfd.send(b'**') break self.sockfd.send(data) fd.close() return "true" else: print(data) return "false" #删除用户文件 def removeU(self,fileName): os.remove(FILE_PATH + self.account + "/" + fileName) return "true" #删除用户文件 def removeF(self,fileName): self.sockfd.send((self.account+' delete@# '+fileName).encode()) # 等待回复 data = self.sockfd.recv(128).decode() if data == "OK": return "true" def menu_display(self): print("\n------命令选择-------") print("*** clist ***") print("*** slist ***") print("*** get list ***") print("*** put list ***") print("*** quit ***") print("----------------------") def run(self,cmd): # 创建套接字 sockfd = socket.socket() try: sockfd.connect(ADDR) except Exception as e: print(e) return result = "" self.sockfd = sockfd # choice(cmd,ftp) if cmd == "slist": result = self.server_list() return result elif cmd == "clist": result = self.client_list() return result elif cmd =='quit': self.do_quit() elif cmd[:3] == 'get': filename = cmd.strip().split(' ')[-1] self.do_get(filename) elif cmd[:3] == 'put': filename = cmd.strip().split(' ')[-1] result = self.do_put(filename) return result elif cmd[:7] == 'removeU': filename = cmd.strip().split(' ')[-1] self.removeU(filename) elif cmd[:7] == 'removeF': filename = cmd.strip().split(' ')[-1] self.removeF(filename) else: print("请输入正确命令!") if __name__ == "__main__": client = Client("ffy") client.run()
运行界面:
总结
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
白云城资源网 Copyright www.dyhadc.com
暂无“python实现ftp文件传输系统(案例分析)”评论...
更新日志
2024年11月08日
2024年11月08日
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]