python实现ftp文件传输系统(案例分析)
最近做了一个简单的文件传输系统,基于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()
运行界面:
总结
到此这篇关于python实现ftp文件传输系统的文章就介绍到这了,更多相关python ftp文件传输内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
- python和C++共享内存传输图像的示例
- Python如何实现自带HTTP文件传输服务
- 详解python logging日志传输
- Python socket连接中的粘包、精确传输问题实例分析
- python实现同一局域网下传输图片
- python实现ftp文件传输功能
- python实现FTP文件传输的方法(服务器端和客户端)
- Python树莓派学习笔记之UDP传输视频帧操作详解
- Python实现基于socket的udp传输与接收功能详解
- python 中Arduino串口传输数据到电脑并保存至excel表格
- python使用socket实现的传输demo示例【基于TCP协议】
- python 使用socket传输图片视频等文件的实现方式
- python 利用opencv实现图像网络传输
相关文章
python机器学习deepchecks库训练检查模型特点探索
这篇文章主要介绍了python机器学习deepchecks库的训练检查模型特点实例探索,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2024-01-01聊聊通过celery_one避免Celery定时任务重复执行的问题
Celery Once 也是利用 Redis 加锁来实现, Celery Once 在 Task 类基础上实现了 QueueOnce 类,该类提供了任务去重的功能,今天通过本文给大家介绍通过celery_one避免Celery定时任务重复执行的问题,感兴趣的朋友一起看看吧2021-10-10
最新评论