最近做了一个简单的文件传输系统,基于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()
运行界面:
总结
华山资源网 Design By www.eoogi.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
华山资源网 Design By www.eoogi.com
暂无评论...
更新日志
2024年11月18日
2024年11月18日
- Elgar-Motdamour-UlfWallin,RolandPontinen(2024)[24bit-96kHz]FLAC
- 苏永康《 笑下去》 新曲+精选[WAV+CUE][1G]
- 周传雄《发觉》[WAV+CUE][1.1G]
- 证声音乐图书馆《真夏派对 x 浩室》[320K/MP3][67.19MB]
- 张镐哲.1994-无助【波丽佳音】【WAV+CUE】
- Relic.2024-浮在虛无的诗意【SEEAHOLE】【FLAC分轨】
- 群星.2001-台语(原主唱)排行总冠军黄金典藏版6CD【柯达唱片】【WAV+CUE】
- 证声音乐图书馆《真夏派对 x 浩室》[FLAC/分轨][379.1MB]
- 徐良《东西世界》[WAV+CUE][1.1G]
- 证声音乐图书馆《真夏派对 x 迪斯可》[320K/MP3][67.9MB]
- TheDutchSwingCollegeBand-JubileeConcert(LiveRemastered2024)(1980)[24Bit-96kHz]FLAC
- 永恒英文金曲精选6《TheBestOfEverlastingFavouritesVol.6》[WAV+CUE]
- ABC唱片-鲍比达·新民乐《满江红》[APE+CUE]
- 许嵩.2014-不如吃茶去【海蝶】【WAV+CUE】
- 周笔畅.2024-HAVE.A.GOOD.NIGHT【SN.Music】【FLAC分轨】