Python3 实现FTP功能
- 目录结构:
FTP_project/
├── FTP_client
│ ├── ftp_client.py
│ └── __init__.py
└── FTP_server
├── bin
│ ├── ftp_server.py
│ └── __init__.py
├── conf
│ ├── accounts.cfg
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ └── settings.cpython-36.pyc
│ └── settings.py
├── core
│ ├── __init__.py
│ ├── main.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ ├── main.cpython-36.pyc
│ │ └── server.cpython-36.pyc
│ └── server.py
├── home
│ ├── __init__.py
│ ├── monitor
│ │ └── __init__.py
│ └── root
└── logger
└── __init__.py
- 代码相关
import optparse, socket
import configparser
import json
import os, sys STATUS_CODE = {
250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
251 : "Invalid cmd ",
252 : "Invalid auth data",
253 : "Wrong username or password",
254 : "Passed authentication", 800 : "the file exist,but not enough ,is continue? ",
801 : "the file exist !",
802 : " ready to receive datas", 900 : "md5 valdate success" } class ClientHandler(): def __init__(self):
# 解析python FTP_client 后面接的参数
self.op = optparse.OptionParser() self.op.add_option('-s','--server',dest='server')
self.op.add_option('-P','--port',dest='port')
self.op.add_option('-u','--username',dest='username')
self.op.add_option('-p','--password',dest='password')
# options(定义的参数),args(未定义的参数)
self.options, self.args = self.op.parse_args()
self.verify_args(self.options, self.args)
self.make_connecton()
self.mainPath = os.path.dirname(os.path.abspath(__file__))
self.last = 0 def verify_args(self, options, args):
server = options.server
port = options.port
username = options.username
password = options.password
if int(port) > 0 and int(port) < 65535:
return True
else:
exit('The port is in 0-65535') def make_connecton(self):
self.sock = socket.socket()
self.sock.connect((self.options.server, int(self.options.port))) def interaction(self): #登陆函数
print('begin to interaction....')
#验证登陆信息
if self.authenticate():
while 1:
cmd_info = input('[%s]' %self.current_dir).strip() # put 12.png images cmd_list = cmd_info.split()
if hasattr(self, cmd_list[0]):
func = getattr(self, cmd_list[0])
func(*cmd_list)
else:
print('Commond is not found!') def authenticate(self): # 账号密码输入
if self.options.username is None or self.options.password is None:
username = input('username: ')
password = input('password: ')
return self.get_auth_result(username,password)
return self.get_auth_result(self.options.username, self.options.password) def response(self):
data = self.sock.recv(1024).decode('utf8')
data = json.loads(data)
return data def get_auth_result(self, user, pwd):
data = {
'action':'auth',
'username':user,
'password':pwd
} self.sock.send(json.dumps(data).encode('utf8'))
response = self.response()
print('response:' ,response['status_code'])
if response['status_code'] == 254:
self.user = user
self.current_dir = user
print(STATUS_CODE[254])
return True
else:
print(STATUS_CODE[response['status_code']]) def put(self, *cmd_list):
# put file_name 路径
action, local_path, target_path=cmd_list
local_path = os.path.join(self.mainPath, local_path ) file_name = os.path.basename(local_path)
file_size = os.stat(local_path).st_size data = {
'action':'put',
'file_name':file_name,
'file_size':file_size,
'target_path':target_path
} self.sock.send(json.dumps(data).encode('utf8'))
is_exist = self.sock.recv(1024).decode('utf8')
##########################
has_sent = 0
if is_exist == '':
# 文件不完整
choice = input('The file exist,but not enouth,is continue? [Y/N]').strip()
if choice.upper() == 'Y':
self.sock.sendall('Y'.encode('utf8'))
continue_position = self.sock.recv(1024).decode('utf8')
has_sent += int(continue_position)
else:
self.sock.sendall('N'.encode('utf8')) elif is_exist == '':
# 文件完全存在
print('The file exist!')
return
else:
pass f = open(local_path, 'rb')
while has_sent < file_size:
data = f.read(1024)
self.sock.sendall(data)
has_sent += len(data)
self.show_progress(has_sent, file_size)
f.close()
print('put success') def show_progress(self, has, total):
rate = float(has)/float(total)
rate_num = int(rate * 100)
if self.last != rate_num:
sys.stdout.write('%s%% %s\r' %(rate_num,'#'*rate_num))
self.last = rate_num def ls(self, *cmd_list):
data = {'action':'ls'}
self.sock.sendall(json.dumps(data).encode('utf8'))
data = self.sock.recv(1024).decode('utf8')
print(data) def cd(self, *cmd_list):
# cd images
data = {
'action':'cd',
'dirname':cmd_list[1]
}
self.sock.send(json.dumps(data).encode('utf8'))
data = self.sock.recv(1024).decode('utf8')
if data != 'Directory is not exist!':
self.current_dir = os.path.basename(data)
else:
print(data) def mkdir(self, *cmd_list):
data = {
'action':'mkdir',
'dirname':cmd_list[1]
} self.sock.sendall(json.dumps(data).encode('utf8'))
ret = self.sock.recv(1024).decode('utf8')
print(ret) def rm(self, *cmd_list):
data = {
'action':'rm',
'file_name':cmd_list[1]
}
self.sock.send(json.dumps(data).encode('utf8'))
data = self.sock.recv(1024).decode('utf8')
print(data) def pwd(self, *cmd_list):
data = {'action':'pwd'}
self.sock.sendall(json.dumps(data).encode('utf8'))
data = self.sock.recv(1024).decode('utf8')
print(data) def quit(self, *cmd_list):
data = {'action':'quit'} ch = ClientHandler() ch.interaction()ftp_client.py
# coding=gbk import os, sys
PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(PATH) from core import main if __name__ == '__main__':
main.ArgvHandler()ftp_server.py
[DEFAULT] [monitory]
Password = 123
Quotation = 100 [root]
Password = root
Quotation = 100accounts.cfg
import os , sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) IP="127.0.0.1"
PORT = 8080 ACCOUNT_PATH = os.path.join(BASE_DIR,"conf",'accounts.cfg')settings.py
import os, sys
import optparse, socketserver
# PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# sys.path.append(PATH)
from conf import settings
from core import server class ArgvHandler():
def __init__(self):
self.op = optparse.OptionParser()
# self.op.add_option('-s','--s',dest = 'server')
# self.op.add_option('-P','--port',dest = 'port')
options, args = self.op.parse_args() # python ftp_server.py -s 127.0.0.1 -P 8080 123
# options:add_option配置过的参数,args:add_option中没有定义的参数
# print(options.server)
# print(options.port)
# print(args) self.verify_args(options, args) def verify_args(self, options, args):
if args:
cmd = args[0]
if hasattr(self, cmd):
func = getattr(self, cmd)
func()
else:
print('There is no such parameter')
else:
print('Usage [start]') def start(self):
print('server is working')
s = socketserver.ThreadingTCPServer((settings.IP,settings.PORT), server.ServerHandler)
s.serve_forever() def help(self):
passmain.py
import socketserver, configparser
import json
from conf import settings
import os, sys STATUS_CODE = {
250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
251 : "Invalid cmd ",
252 : "Invalid auth data",
253 : "Wrong username or password",
254 : "Passed authentication", 800 : "the file exist,but not enough ,is continue? ",
801 : "the file exist !",
802 : " ready to receive datas", 900 : "md5 valdate success" } class ServerHandler(socketserver.BaseRequestHandler): def handle(self):
while True:
#conn = self.request data=self.request.recv(1024).strip()
if len(data)==0:break data=json.loads(data.decode("utf8"))
print("data:",data)
'''
{'action':'auth',
'username':'xxxx',
'pwd':123
}
'''
if data.get('action'):
if hasattr(self, data.get('action')):
func = getattr(self, data.get('action'))
func(**data)
else:
print('Invalid cmd')
else:
print('Invalid cmd2') def send_reponse(self, status_code):
response = {'status_code':status_code}
self.request.sendall(json.dumps(response).encode('utf8')) def auth(self, **data):
username = data['username']
password = data['password']
user = self.authenticate(username, password) if user:
self.send_reponse(254)
else:
self.send_reponse(253) def authenticate(self, user, pwd):
cfg = configparser.ConfigParser()
cfg.read(settings.ACCOUNT_PATH) if user in cfg.sections():
if cfg[user]['Password'] == pwd:
self.user=user
self.mainPath = os.path.join(settings.BASE_DIR, 'home', self.user)
print('passwd authentication')
return user def put(self, **data):
print('data')
file_name = data.get('file_name')
file_size = data.get('file_size')
target_path = data.get('target_path') abs_path = os.path.join(self.mainPath, target_path, file_name) #######################################传输
has_received = 0
if os.path.exists(abs_path):
file_has_size = os.stat(abs_path).st_size
if file_has_size < file_size:
# 断点续传
self.request.sendall(''.encode('utf8'))
choice = self.request.recv(1024).decode('utf8')
if choice == 'Y':
self.request.sendall(str(file_has_size).encode('utf8'))
has_received = file_has_size
f = open(abs_path, 'ab')
else:
f = open(abs_path, 'wb')
else:
# 文件完全存在
self.request.sendall(''.encode('utf8'))
return else:
self.request.sendall(''.encode('utf8'))
f = open(abs_path, 'wb') while has_received < file_size:
try:
data = self.request.recv(1024)
except Exception as e:
break
f.write(data)
has_received += len(data)
f.close() def ls(self,**data):
file_list = os.listdir(self.mainPath) # 加入当前目录下的文件到列表
file_str='\n'.join(file_list)
if not len(file_str):
file_str='<empty dir> '
self.request.sendall(file_str.encode('utf8')) def cd(self, **data):
dirname = data.get('dirname') if dirname == '..':
self.mainPath = os.path.dirname(self.mainPath)
self.request.sendall(self.mainPath.encode('utf8'))
elif os.path.exists(os.path.join(self.mainPath, dirname)):
self.mainPath = os.path.join(self.mainPath, dirname)
self.request.sendall(self.mainPath.encode('utf8'))
else:
self.request.sendall('Directory is not exist!'.encode('utf8')) def mkdir(self, **data):
dirname = data.get('dirname')
# 新目录名
path = os.path.join(self.mainPath, dirname)
# 判断目录名是否存在
if not os.path.exists(path):
if '/' in dirname:
os.makedirs(path)
else:
os.mkdir(path)
self.request.sendall('create success'.encode('utf8'))
else:
self.request.sendall('dirname is exist'.encode('utf8')) def rm(self, **data):
filename = data.get('file_name')
filename1 = os.path.join(self.mainPath, filename)
os.remove(filename1)
self.request.sendall('file is removed!'.encode('utf8')) def pwd(self, **data):
self.request.sendall(self.mainPath.encode('utf8'))server.py
Python3 实现FTP功能的更多相关文章
- libcurl编译使用,实现ftp功能
Libcurl实现ftp的下载,上传功能.版本为curl-7.63.0 1.编译vs2015 参考资料:https://blog.csdn.net/yaojingkao/article/details ...
- 使用commons-net做FTP功能的异常 java.lang.ClassNotFoundException: org.apache.oro.text.regex.Malformed
最近使用Apache的commons-net.jar做FTP上传下载功能,点击“上传”的时候报错,如下: java.lang.ClassNotFoundException: org.apache.or ...
- python网络编程--socketserver 和 ftp功能简单说明
1. socketserver 我们之前写的tcp协议的socket是不是一次只能和一个客户端通信,如果用socketserver可以实现和多个客户端通信.它是在socket的基础上进行了一层封装,也 ...
- Win7的ftp功能
ftp作为文件传输协议,在一些特殊情况下用这种文件传输是比较方便的,并且win7本身也支持这个功能,在控制面板--->程序-->打开或关闭Windows功能,安装即可: 然后在管理控制台中 ...
- python socketserver 实现 ftp功能
需求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 允许用户查看当前目 ...
- python 基于windows环境的ftp功能
描述: 1.基于备份服务器部署的py程序,将需要备份主机目录下的内容下载至备份服务器(服务端和远端都是windows server 2008) 2.py程序部署在windows服务器,后台运行,基于b ...
- centos启用ftp功能
1.安装vsftpd组件,安装完后,有/etc/vsftpd/vsftpd.conf 文件,用来配置,还有新建了一个ftp用户和ftp的组,指向home目录为/var/ftp,默认是nologin(不 ...
- 给ubuntu开通FTP功能
一.安装vsftp安装: sudo apt-get install vsftpd 二.启动.停止.重启vsftp 启动vsftp:sudo service vsftpd start 三.创建ftp用户 ...
- day29 socketsever ftp功能简单讲解
今日所学 一.ftp上传简单实例 二.socketsever的固定用法 三.验证合法性连接 1.ftp上传实例 这个题目是我们现在网络编程比较基础一点的题目 下面我们只写简单上传的代码 上传服务端的代 ...
随机推荐
- sql 、linq、lambda 查询语句
http://www.cnblogs.com/lei2007/archive/2011/07/21/2113161.html
- python locust 进行压力测试
最近公司项目周期比较赶, 项目是软硬结合,在缺少硬件的情况下,通过接口模拟设备上下架和购买情况,并进行压力测试, 本次主要使用三个接口 分别是3个场景: 生成商品IP, 对商品进行上架, 消费者购买商 ...
- 【ABAP系列】SAP ABAP SY-SUBRC的含义解析
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP SY-SUBR ...
- 【Qt开发】解决Qt5.7.0中文显示乱码的问题
[Qt开发]解决Qt5.7.0中文显示乱码的问题 亲测可用: 乱码主要是编码格式的问题,这里可以通过Edit菜单中选择当前文档的编码方式,选择按照UTF-8格式保存,然后输入对应的中文,保存,然后运行 ...
- C语言中,当计算字符数组长度时,用sizeof 和strlen 的原理及两者的区别
字符数组的长度计算:必须以终止符’\0'作为边界,但对字符数组赋值时,有两种方式: 1:定义时用字符初始化 (1)char chs[7] = {'a', 'c', '0', 'z', '3','d'} ...
- 极*Java速成教程 - (6)
Java高级特性 String String是Java中的字符串类型,字符串类型在内存中是一个不可变的对象.如果要对字符串对象进行修改,如果是较少的修改可以使用+运算符,Java会自动进行优化,但如果 ...
- 【学习总结】快速上手Linux玩转典型应用-第5章-远程连接SSH专题
课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. 认识SSH 2. 服务器安装SSH服务 3. 客户端安装SSH工具 4. 客户端链接SSH服务 5. SSH config 6. SSH ...
- python multiprocessing模块
python multiprocessing模块 原文地址 multiprocessing multiprocessing支持子进程.通信和共享数据.执行不同形式的同步,提供了Process.Queu ...
- 46. Permutations (JAVA)
Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] O ...
- mac 命令行终端 设置代理
环境: macOS Mojave 10.14.3 iTrem 2 3.2.8 酸酸乳1.1.4.4-R8 查看自己命令行的状态 curl ip.gs 正式开始 一.首先检查自己的酸酸乳是否正常,并在高 ...