调用功能函数以及对参数数量进行判断
客户端 server 文件夹下 FTPClient.py
def interactive(self):
"""交互指令,调用功能函数"""
if self.auth(): # 登陆成功
while True:
command = input(self.show_to_client).strip()
if not command:continue
command = command.split()
action_type = command[0] # 用户输入的命令类似于终端命令
if hasattr(self, action_type): # 如果 客户端的类中有 action_type 的函数方法
func = getattr(self, action_type) # 执行
func(command[1: ]) # 执行的函数传入的参数应为 action_type 之后的部分
else:
print("Error: this command does not exist !")
def parameter_length_judgment(self, command,min_size=None, most_size=None, exact_size=None):
"""判断命令中参数个数是否符合规范,比如说 下载功能 至少要提供文件名的参数"""
if min_size: # 至少提供的参数个数
if len(command) < min_size:
print("Error: supply parameter at least %s, but supply %s parameter" % (min_size, len(command)))
return False
if most_size: # 可以提供的最多参数数量
if len(command) > most_size:
print("Error: supply parameter at most %s, but supply %s parameter" % (most_size, len(command)))
return False
if exact_size: # 应该提供的精确的参数数量
if len(command) != exact_size:
print("Error: should supply %s parameter, but supply %s parameter" % (exact_size, len(command)))
return False
return True
状态码的变化
服务端 lib 文件夹下 main.py
# 状态码
STATUS_CODE = {
200: "User login succeeded !", # 用户登陆成功
201: "Error: wrong username or wrong password !", # 错误用户名或密码
202: "Action_type does not exist !", # 没有该函数可以执行
300: "Check Dir !",
301: "Dir does not exist !"
}
查看服务端当前目录
客户端 server 文件夹下 FTPClient.py
def ls(self, command):
"""查看服务端当前目录"""
# 因为该函数是查看服务端当前目录,所以不用管会传入多少参数,即最少传入 0 给参数
if self.parameter_length_judgment(command=command, min_size=0): # if True
self.create_header_send(action_type="ls")
response = self.get_response()
# print(response)
# 消息的总大小
total_size = response.get("size")
# 为断点续存做准备
self.current_dir = response.get("current_dir")
recv_size = 0
res = b""
# 循环接收信息
while recv_size < total_size:
data = self.client.recv(self.MSG_SIZE)
res += data
recv_size += len(data)
else:
print(res.decode("gbk"))
服务端 lib 文件夹下 main.py
用户登录成功时,增加的代码
if str(md5_password) == str(ini_password): # 如果密码正确
self.send_response(status_code=200)
self.current_dir = os.path.join(self.user_home, username) # 增加的代码部分
# print(self.current_dir)
实现功能的代码
def _ls(self, header_dic):
"""查看当前目录"""
# 执行终端命令,并获取结果
obj = subprocess.Popen("dir %s" % self.current_dir, shell=True,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
self.send_response(status_code=300, size=len(stdout)+len(stderr), current_dir=self.current_dir) # 当前目录为断点续存做准备
# 发送执行结果
self.conn.send(stderr)
self.conn.send(stdout)
查看客户端目录
客户端 server 文件夹下 FTPClient.py
def dir(self, command):
"""查看客户端下的目录"""
# 由于是查看客户端目录,所以可以不输入路径或是输入路径,即传入的参数最多为 1,1 是目录路径
if self.parameter_length_judgment(command, most_size=1):
if command: # 如果 command 不为空
path = command[0]
else:
path = ""
# 执行终端命令
obj = subprocess.Popen("dir %s" % path, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
print(stdout.decode("gbk"), stderr.decode("gbk"))
切换目录
客户端 server 文件夹下 FTPClient.py
def cd(self, command):
"""切换服务端目录"""
# 切换服务端目录,所以必须输入路径,即传入的参数最少为 1,1 是目录路径,多于 1 的部分不需要考虑
if self.parameter_length_judgment(command, most_size=1):
cmd = command[0]
self.create_header_send(action_type="cd", cmd=cmd)
# 获取 response
response = self.get_response()
if response.get("status_code") == 300:
show_to_client = response.get("show_to_client")
self.show_to_client = "[%s]" % show_to_client
self.current_dir = response.get("current_dir")
else:
print(response.get("status_msg"))
服务端 lib 文件夹下 main.py
def _cd(self, header_dic):
"""切换目录,但最高一级只到 \\home\\username"""
cmd = header_dic.get("cmd")
full_path = os.path.abspath(os.path.join(self.current_dir, cmd)) # 拼接路径,返回绝对路径,避免出现 \\home\\username\\..\\.. 的情况出现
if os.path.isdir(full_path): # 如果路径存在
if full_path.replace(self.user_home, "") and self.user_home in full_path: # 保证路径不会到达 home 一级
obj = subprocess.Popen("cd %s" % full_path, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
self.current_dir = full_path
self.send_response(status_code=300,
show_to_client = full_path.replace(self.user_home, ""),
current_dir=self.current_dir) # 当前目录为断点续存做准备
else:
self.send_response(status_code=301) # 对用户来说路径不存在
else:
self.send_response(status_code=301) # 对用户来说路径不存在