def start(self): """ 启动客户端进程 :return: """ print(lib.b2s(self.__sk.recv(200))) #显示欢迎信息 self.auth() while True: #循环获取用户输入的命令,如果输入quit退出循环,并退出客户端 user_input = input('%s:%s ftp>> ' % (self.current_user, self.current_path)).strip() if len(user_input) == 0: continue user_input_split = user_input.split() #分割用户输入的命令 # print(user_input_split) if user_input.startswith('quit'): #判断用户输入的命令,如果quit退出循环,并退出客户端 self.__sk.sendall(lib.s2b("quit")) break # if user_input_split[0] == 'put' or user_input_split[0] == 'get' : if hasattr(self, user_input_split[0]): #判断用户命令是否有对应方法 func = getattr(self, user_input_split[0]) #获取方法 func(user_input_split) # print(func) else: print("\033[31;0m无效的指令!\033[0m") FTPClient.print_help_msg() continue
def local_cmd(self, user_input_split): #定义模拟ssh远程执行命令函数 user_cmd = user_input_split[0] #分割用户输入,获取要执行的操作命令 if len(user_input_split) == 2: #如果包含参数,分割命令参数 args = user_input_split[1] msg_data = { "action": user_cmd, "args": args } #将要执行的命令和参数封装到字典传送给客户端 elif len(user_input_split) == 1: msg_data = { "action": user_cmd, } self.__sk.sendall(bytes(json.dumps(msg_data), encoding='utf8')) #发送Linux命令 clinet_recv_ack_msg = self.__sk.recv(1024).decode() #客户端接收命令执行结果大小 # print(clinet_recv_ack_msg) if clinet_recv_ack_msg.startswith( 'CMD_RESULT_SIZE'): #客户端接收到服务器端发送的命令执行结果大小后,准备发送确认接收消息 cmd_result_size = int(clinet_recv_ack_msg.split('|')[1]) self.__sk.sendall(lib.s2b('start')) #发送确认开始指令 recv_size = 0 #设定接收初始接收大小为0 recv_msg = b'' while recv_size < cmd_result_size: #当接收结果大小与命领结果大小一致时,停止接收 recv_data = self.__sk.recv(1024) recv_msg += recv_data recv_size += len(recv_data) # print('Cmd result size:%s Receive size:%s'%(cmd_result_size,recv_size)) print(lib.b2s(recv_msg))
def du(self, user_input): """ 查看剩余磁盘额度 :return: """ msg_dict = { "action": "du", } self.__sk.sendall(bytes(json.dumps(msg_dict), encoding='utf8')) print(lib.b2s(self.__sk.recv(1024)))
def put(self, user_input): #客户端上传文件方法 if len(user_input) == 2: abs_filepath = os.path.join(self.current_home_path, user_input[1]) print(abs_filepath) if os.path.isfile(abs_filepath): #判断上传文件是否存在 filesize = os.stat(abs_filepath).st_size #获取上传文件大小 filename = abs_filepath.split("/")[-1] #获取上传文件名 md5value = lib.show_md5(abs_filepath) #获取上传文件md5值 print('file:%s size:%s' % (abs_filepath, filesize)) #打印文件md5值 msg_data = { "action": "put", "filename": filename, "filesize": filesize, "md5value": md5value, } print(msg_data) self.__sk.send( bytes(json.dumps(msg_data), encoding="utf-8")) #传送给服务器端要执行的操作及文件信息(大小,文件名等) server_confirmation_msg = self.__sk.recv( 1024) #客户端接收到服务器端确认接收消息 print(server_confirmation_msg) confirm_data = json.loads( server_confirmation_msg.decode()) #将接收消息转化为字典 if confirm_data['status'] == 'normal': #确认可以接收后本地打开文件传输内容 print("start sending file ", filename) send_size = confirm_data.get('filesize') f = open(abs_filepath, 'rb') f.seek(send_size) for line in f: self.__sk.send(line) #一行一行传输文件 send_size += len(line) lib.view_bar(send_size, filesize) #利用进度条工具,显示传输进度 f.close() #关闭文件 resonse = lib.b2s(self.__sk.recv(1024)) print('\nResponse code:%s' % resonse) print("send file done ") elif confirm_data['status'] == 304: print(self.code_list['304']) else: self.code_list.get('307') else: print(self.code_list['401'])
def cd(self, user_input): """ 切换服务器端路径 :param user_input: :return: """ if len(user_input) == 1: path = "." else: path = user_input[1] msg_dict = { "action": "cd", "path": path, } self.__sk.sendall(bytes(json.dumps(msg_dict), encoding='utf8')) response = lib.b2s(self.__sk.recv(4096)) if response == "401": print("401 %s" % self.code_list["401"]) else: # 如果服务器返回正常,将当前目录进行修改 self.current_path = response
def auth(self): """ 认证方法。错误输入超过三次,退出程序 :return: """ times = 0 while True: if times >= 3: self.__sk.sendall(lib.s2b("exit")) self.__sk.close() exit('输入密码错误已达三次,程序退出') username = input('username:\n').strip() #获取用户名 if not username: print('用户名不能空') continue password = input('password:\n').strip() #获取用户密码 if not password: print('密码不能为空') continue self.__sk.sendall( lib.s2b(('auth|%s|%s') % (username, lib.md5(password)))) #调用服务端的验证方法,验证用户名密码 res = lib.b2s(self.__sk.recv(200)) #获取验证结果 if res == '200': #如果通过验证,修改当前登录用户和状态 self.current_user = username self.__is_login = True self.current_home_path = os.path.join(conf.USERS_HOME_DIR, self.current_user) if not os.path.exists(self.current_home_path): os.makedirs(self.current_home_path) pwd = os.sep return pwd elif res == '201': print(conf.CODE_LIST['201']) times += 1 continue