FTP上传下载文件(面向对象版)
# 服务端
import socketserver
import os
import json
import hashlib
import struct
class MySocketServer(socketserver.BaseRequestHandler):
users = []
@staticmethod
def get_dic(): # 获取密码库
user_dic = {}
file_name = 'register'
if file_name not in os.listdir(os.path.dirname(__file__)):
return user_dic
else:
with open(os.path.join(os.path.dirname(__file__), file_name), mode='r', encoding='utf-8') as f:
for line in f:
if line:
username, psw = line.strip().split('|')
user_dic[username] = psw
return user_dic
def logon(self): # 注册
user_dic = self.get_dic()
time = 3
while time > 0:
username, psw = self.request.recv(1024).decode('utf-8').split('|')
if 0 <= len(username) <= 20 and 6 <= len(psw) <= 20 and (username not in user_dic):
with open(os.path.join(os.path.dirname(__file__), 'register'), mode='a', encoding='utf-8') as f:
md5 = hashlib.md5()
md5.update(psw.encode('utf-8'))
f.write(f'{username}|{md5.hexdigest()}\n')
self.request.send('True'.encode())
MySocketServer.users.append(username)
self.user = username
return True
else:
time -= 1
self.request.send(str(time).encode('utf-8'))
return False
def login(self): # 登录
time = 3
user_dic = self.get_dic()
while time > 0:
username, psw = self.request.recv(1024).decode('utf-8').split('|')
md5 = hashlib.md5()
md5.update(psw.encode('utf-8'))
if user_dic.get(username) == md5.hexdigest() and username not in MySocketServer.users:
self.request.send('True'.encode())
MySocketServer.users.append(username)
self.user = username
return True
else:
time -= 1
self.request.send(str(time).encode('utf-8'))
return False
def up(self): # 上传
while 1:
len_head_dic = struct.unpack('i', self.request.recv(4))[0]
head_dic = json.loads(self.request.recv(len_head_dic).decode('utf-8'))
file_name = head_dic['file_name']
file_md5 = head_dic['file_md5']
file_size = head_dic['file_size']
if self.user not in os.listdir(os.path.join(os.path.dirname(__file__), '用户文件')):
os.makedirs(f'用户文件/{self.user}')
file_path = os.path.join(os.path.dirname(__file__), f'用户文件/{self.user}', file_name)
with open(file_path, mode='wb') as f:
md5 = hashlib.md5()
len_data = 0
while len_data < file_size:
data = self.request.recv(1024)
len_data += len(data)
md5.update(data)
f.write(data)
data_md5 = md5.hexdigest()
if data_md5 == file_md5:
self.request.send('True'.encode('utf-8'))
return True
else:
self.request.send('False'.encode('utf-8'))
def down(self): # 下载
file_path = os.path.join(os.path.dirname(__file__), '用户文件')
file_user = os.listdir(file_path)
if self.user not in file_user or not os.listdir(os.path.join(file_path, f'{self.user}')):
self.request.send('False'.encode('utf-8'))
else:
file_lst = os.listdir(os.path.join(file_path, f'{self.user}'))
file_show = ''
for n, file in enumerate(file_lst, 1):
file_show += f'序号:{n}\t文件名:{file}\n'
to_client = f'可下载文件:\n{file_show}'.encode('utf-8')
self.request.send(to_client)
while 1:
from_client = self.request.recv(1024).decode('utf-8')
try:
with open(os.path.join(file_path, f'{self.user}', file_lst[int(from_client) - 1]), mode='rb') as f:
file_size = 0
md5 = hashlib.md5()
while 1:
data = f.read(1024)
if data:
md5.update(data)
file_size += len(data)
else:
break
file_md5 = md5.hexdigest()
self.request.send('True'.encode('utf-8'))
except Exception:
self.request.send('False.'.encode('utf-8'))
continue
else:
head_dic = {
'file_md5': file_md5,
'file_name': file_lst[int(from_client) - 1],
'file_size': file_size
}
head_dic_json_bytes = json.dumps(head_dic).encode('utf-8')
len_head_dic_bytes = struct.pack('i', len(head_dic_json_bytes))
self.request.send(len_head_dic_bytes)
self.request.send(head_dic_json_bytes)
with open(os.path.join(file_path, f'{self.user}', file_lst[int(from_client) - 1]), mode='rb') as f:
while 1:
data = f.read(1024)
if data:
self.request.send(data)
else:
return True
def handle(self):
while 1:
try:
from_client = self.request.recv(1024).decode('utf-8')
func = getattr(self, from_client)
ret = func()
if ret == False:
break
except Exception:
MySocketServer.users.remove(self.user)
break
server = socketserver.ThreadingTCPServer(('192.168.13.19', 2020), MySocketServer)
server.serve_forever() # 对象执行serve_forever方法,开启服务端
# 客户端
import socket
import os
import json
import hashlib
import struct
import sys
import time
def progress(percent, width=50): # 打印进度条
if percent >= 1:
percent = 1
show_str = ('%%-%ds' % width) % (int(width*percent)*'|')
print('\r%s %d%%' %(show_str, int(100*percent)), end='')
class MyClient:
login_logon = {'1': 'login',
'2': 'logon'}
func_dic = {
'1': 'up',
'2': 'down',
'3': 'exit'
}
def __init__(self, name, ip, port):
self.name = name
self.socket = socket.socket()
self.socket.connect((ip, port))
def logon(self): # 注册
print('-----欢迎访问注册页面-----')
while 1:
username = input('请输入用户名:').strip()
psw = input('请输入密码:').strip()
self.socket.send(f'{username}|{psw}'.encode('utf-8'))
from_server = self.socket.recv(1024).decode('utf-8')
if from_server == 'True':
print('恭喜你,注册成功~~~~~~~~')
return True
elif from_server == '0':
print('啊哈,注册失败了,正在退出....')
return False
else:
print(f'再来一次吧,还有{from_server}次机会~~~~')
def login(self): # 登录
print('-----欢迎访问登录页面-----')
while 1:
username = input('请输入用户名:').strip()
psw = input('请输入密码:').strip()
self.socket.send(f'{username}|{psw}'.encode('utf-8'))
from_server = self.socket.recv(1024).decode('utf-8')
if from_server == 'True':
print('恭喜你,登录成功~~~~~~~~')
return True
elif from_server == '0':
print('啊哈,登录失败了,正在退出....')
return False
else:
print(f'再来一次吧,还有{from_server}次机会~~~~')
def up(self): # 上传
print('-----欢迎访问上传页面-----')
while 1:
file_path = input('请输入上传的文件路径:').strip()
try:
with open(file_path, mode='rb') as f:
file_size = 0
md5 = hashlib.md5()
while 1:
data = f.read(1024)
if data:
md5.update(data)
file_size += len(data)
else:
break
file_md5 = md5.hexdigest()
except Exception:
print('路径错误,请重新输入.')
continue
else:
head_dic = {
'file_md5': file_md5,
'file_name': os.path.basename(file_path),
'file_size': file_size
}
head_dic_json_bytes = json.dumps(head_dic).encode('utf-8')
len_head_dic_bytes = struct.pack('i', len(head_dic_json_bytes))
self.socket.send(len_head_dic_bytes)
self.socket.send(head_dic_json_bytes)
with open(file_path, mode='rb') as f:
data_size = 0
while 1:
data = f.read(1024)
if data:
self.socket.send(data)
data_size += len(data)
percent = data_size / file_size
progress(percent, width=70)
else:
break
from_server = self.socket.recv(1024).decode('utf-8')
if from_server == 'True':
print('恭喜你,上传成功.')
return True
else:
print('啊哈,上传失败.')
def down(self): # 下载
print('-----欢迎访问下载页面-----')
from_server = self.socket.recv(1024).decode('utf-8')
if from_server == 'False':
print('你的云盘为空,请先上传文件~~~~~~')
else:
print(from_server)
while 1:
choice = input('请输入选择的序号:').strip().encode('utf-8')
self.socket.send(choice)
return_from_server = self.socket.recv(1024).decode('utf-8')
if return_from_server == 'True':
len_head_dic = struct.unpack('i', self.socket.recv(4))[0]
head_dic = json.loads(self.socket.recv(len_head_dic).decode('utf-8'))
file_name = head_dic['file_name']
file_md5 = head_dic['file_md5']
file_size = head_dic['file_size']
file_path = os.path.join(os.path.dirname(__file__), '下载', file_name)
with open(file_path, mode='wb') as f:
md5 = hashlib.md5()
len_data = 0
while len_data < file_size:
data = self.socket.recv(1024)
len_data += len(data)
md5.update(data)
f.write(data)
percent = len_data / file_size
progress(percent, width=70)
percent = len_data / file_size
progress(percent, width=70)
data_md5 = md5.hexdigest()
if data_md5 == file_md5:
print('下载成功.')
return True
else:
print('下载失败.')
else:
print('输入错误,请重新输入.')
def exit(self): # 退出
print('正在退出~~~~~~')
exit()
def run(self):
print('-----[1]登录[2]注册-----')
while 1:
choice = input('请输入选项:').strip()
if choice in self.login_logon:
self.socket.send(self.login_logon[choice].encode('utf-8'))
func = getattr(self, self.login_logon[choice])
ret = func()
if ret:
while 1:
print('-----[1]上传[2]下载[3]退出-----')
choice_func = input('请输入选项:').strip()
if choice in self.func_dic:
self.socket.send(self.func_dic[choice_func].encode('utf-8'))
method = getattr(self, self.func_dic[choice_func])
method()
else:
print('输入错误,请重新输入.')
else:
break
else:
print('输入错误,请重新输入.')
client = MyClient('客户端', '192.168.13.19', 2020)
client.run()
FTP上传下载文件(面向对象版)的更多相关文章
- FTP上传下载文件(函数简易版)
FTP上传下载文件(函数简易版) # 服务端 import socket import json import hashlib import struct import os user_dic = { ...
- java客户端调用ftp上传下载文件
1:java客户端上传,下载文件. package com.li.utils; import java.io.File; import java.io.FileInputStream; import ...
- shell ftp上传下载文件
1. ftp自动登录批量下载文件. #####从ftp服务器上的/home/data 到 本地/home/databackup#### #!/bin/bash ftp -n<<! open ...
- shell脚本实现ftp上传下载文件
前段时间工作中需要将经过我司平台某些信息核验数据提取后上传到客户的FTP服务器上,以便于他们进行相关的信息比对核验.由于包含这些信息的主机只有4台,采取的策略是将生成的4个文件汇集到一个主机上,然后在 ...
- python实现支持目录FTP上传下载文件的方法
#!/usr/bin/env python # -*- coding: utf-8 -*- import ftplib import os import sys class FTPSync(objec ...
- 如何通过SecureCRT FTP上传下载文件
通过SecureCRT FTP方式从一台机器下载文件到另一台机器上: [root@TEST144239 ~]# ftp 10.30.1.25 Connected to 10.30.1.25 (10. ...
- ftp上传下载文件
客户端client: import os import json import socket import struct sk = socket.socket() sk.connect(('127.0 ...
- shell通过ftp实现上传/下载文件
直接代码,shell文件名为testFtptool.sh: #!/bin/bash ########################################################## ...
- JAVA 实现FTP上传下载(sun.net.ftp.FtpClient)
package com.why.ftp; import java.io.DataInputStream; import java.io.File; import java.io.FileInputSt ...
随机推荐
- 并行开发 2.plink
原文:8天玩转并行开发——第二天 Task的使用 在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于 “任务的编程模型”所冲击, ...
- asp.net ajax的使用
参考:https://www.cnblogs.com/acles/articles/2385648.html https://www.cnblogs.com/xujingyang/p/5560646. ...
- UIView与CALayer 区别
在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮.一个文本标签.一个文本输入框.一个图标等等,这些都是UIView. 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个 ...
- 2018-8-10-win10-uwp-毛玻璃
title author date CreateTime categories win10 uwp 毛玻璃 lindexi 2018-08-10 19:16:50 +0800 2018-2-13 17 ...
- 从零开始的PHP生活Day1
PHP 什么是PHP? PHP(Hypertext Preprocessor,超文本预处理器)是一种服务器端的.跨平台的.HTML嵌入式的弱类型开源脚本语言. 1.服务器端:PHP需要使用服务器软件进 ...
- 脚本_根据 md5 校验码,检测文件是否被修改
#!bin/bash#功能:根据 md5 校验码,检测文件是否被修改#作者:liusingbon#本示例脚本检测的是/etc 目录下所有的 conf 结尾的文件,根据实际情况,您可以修改为其他目录或文 ...
- BZOJ-3143/洛谷3232 游走(HNOI2013)概率DP
题意:给定n个点m条边.每条边的权值还没决定,权值大小为从1到m.从1出发每次等概率选一条出边向下走,直到走到n点停止,路径代价就是边权总和.由你来决定边权来使得上诉路径代价期望值最小. 解法:点这么 ...
- svnkit 异常:Exception in thread "main" org.tmatesoft.svn.core.SVNException: svn: E200030: SQLite error
https://stackoverflow.com/questions/16063105/org-tmatesoft-sqljet-core-sqljetexception-busy-error-co ...
- 动态规划之数字三角形(POJ1163)
在下面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或 右下走.只需要求出这个最大和即可,不必给出具体路径. 既然求目标问题是根据查表得来的,自然 ...
- 注意!黑客可以通过CSS3功能攻击浏览器
随着通过HTML5和CSS3引入的惊人数量的功能,浏览器的攻击面也相应增长.因此,这些功能之间的交互可能会导致意外行为影响用户的安全,这并不奇怪.在这篇文章中,中国知名黑客安全组织东方联盟描述了这样一 ...