def mk_dir(self): data = self.get_dir() dir_name = self.aim print('当前路径下目录') self.show_ls(data) print('当前路径') print(self.current_path) temp_path = os.path.join(self.current_path, dir_name) if temp_path in data[1]['dir']: print('文件夹已经存在!') elif dir_name != '': mk_dir_info = { 'opt': 'mk_dir', 'current_path': self.current_path, 'dir_name': dir_name, 'username': self.usr } # 发送字典 FTP_pipe.sk_send_dic(self.sk, mk_dir_info) # 接收含有文件夹和文件目录的列表 # 获取字典 data = FTP_pipe.sk_recv_dic(self.sk) print('文件夹创建成功!!!') self.show_ls(data) print('当前路径为', self.current_path)
def register(self): while True: username = input('请输入您的用户名(按q退出)>>>') if username == 'q': return {'opt': '注册', '状态': '注册失败'} elif username: while True: pwd = input('请输入您的密码>>>') pwd_again = input('请再次输入您的密码>>>') if pwd == pwd_again: rigester_info = { 'opt': '注册', 'username': username, 'pwd': pwd } # 发送字典 FTP_pipe.sk_send_dic(self.sk, rigester_info) # 接受字典 ret = FTP_pipe.sk_recv_dic(self.sk) print(ret[1]) if ret[0]: print('新建家目录>>>', ret[2]) break else: print('输入密码不一致,请重新输入!')
def get_dir(self): get_dir_dic = { 'opt': 'ls', 'current_path': self.current_path, 'username': self.usr } #发送字典 FTP_pipe.sk_send_dic(self.sk, get_dir_dic) #接收含有文件夹和文件目录的列表 # 获取字典 data = FTP_pipe.sk_recv_dic(self.sk) return data
def download(self): current_path = self.current_path file_name = self.aim local_download_path = input('请输入您要保存的路径>>>') file_li = os.listdir(local_download_path) local_download_file_path = os.path.join(local_download_path, file_name) #判断下载的本地路径下是不是有重名的文件 if file_name in file_li: #文件有三种可能 #·本地大小可能小于服务器文件,且内容相同---->断点续传 #·本地文件大小和服务器文件大小相同,且内容相同---->已经下载了,不能继续下载 #·本地文件和服务器文件仅仅名字一样----->完全不相干,不能继续下载,可改名后下载(以后扩展) #先将本地信息传到服务器,然后服务器传回和本地文件大小相同的内容的md5校验值进行比较 local_dowload_file_size = os.path.getsize(local_download_file_path) local_dowload_file_md5 = self.content_md5(local_download_file_path, local_dowload_file_size) else: local_dowload_file_size = 0 local_dowload_file_md5 = None info_dic = { 'opt': 'download', 'current_path': current_path, 'file_name': file_name, 'root_path': self.root_path, 'local_file_size': local_dowload_file_size, 'local_dowload_file_md5': local_dowload_file_md5 } FTP_pipe.sk_send_dic(self.sk, info_dic) #---->dic_operation ret = FTP_pipe.sk_recv_dic(self.sk) #[False,'本地目标路径上已经有一个完全相同的文件,不用再下载了!'] #[False,'本地目标路径上已经有一个大小完全相同,但是内容不同的文件,不能再下载了!'] #[True, 1, download_file_size] #[False,'不断点续传,那就关了吧!'] #[True,2,download_file_size] #[False,'文件夹错误!'] if ret[0] == False: print(ret[1]) elif ret[0] == True and ret[1] == 1: order = input('你确定要断点续传吗(y/n)>>>') FTP_pipe.sk_send_dic(self.sk, [order]) download_file_size = ret[2] rest_file_size = download_file_size - local_dowload_file_size start_position = local_dowload_file_size client_local_dowload_after_file_md5 = self.recv_file( self.sk, local_download_file_path, rest_file_size, start_position) server_download_after_file_md5 = FTP_pipe.sk_recv_dic(self.sk)[0] if client_local_dowload_after_file_md5 == server_download_after_file_md5: print('断点续传下载成功!!') else: print('断点续传下载失败!') elif ret[0] == True and ret[1] == 2: download_file_size = ret[2] client_local_dowload_after_file_md5 = self.recv_file( self.sk, local_download_file_path, download_file_size, 0) server_download_after_file_md5 = FTP_pipe.sk_recv_dic(self.sk)[0] if client_local_dowload_after_file_md5 == server_download_after_file_md5: print('非断点续传下载成功!')
def login(self): #首先要输入用户名和密码 username = input('请输入您的用户名(按“q”退出)>>>') #如果用户输入q直接退出程序 if username == 'q': return {'opt': '登录', 'status': False} #输入密码 pwd = input('请输入您的密码>>>') #如果用户名和密码不为空,就往服务端发消息,这个消息需要到达的功能 #1.通知服务器这是要登录 #2.包含登录的用户名和密码 if username and pwd: dic_client_info = {'opt': '登录', 'username': username, 'pwd': pwd} #发送字典 FTP_pipe.sk_send_dic(self.sk, dic_client_info) #接受字典 ret = FTP_pipe.sk_recv_dic(self.sk) print(ret[1]) if ret[0]: print('当前所在家目录>>>', ret[2]) self.FTP_client = Cfc.FTP_client(username, ret[2], self.sk) self.FTP_client.choose_operation()
def recv_file(self, sk, client_download_path, rest_file_size, start_position): m = hashlib.md5() with open(client_download_path, mode='ab') as f: f.seek(start_position) block = personal_config_info['BLOCK_SIZE'] total = rest_file_size num = start_position while rest_file_size: if rest_file_size > block: content = FTP_pipe.sk_recv_dic(sk)[0] rest_file_size -= block num += block else: content = FTP_pipe.sk_recv_dic(sk)[0] rest_file_size -= rest_file_size num += rest_file_size if content == b'': break f.write(content.encode(self.coding)) m.update(content.encode(self.coding)) # self.processBar(num,total) return m.hexdigest()
def file_send(self, sk, file_path, rest_file_size, start_point): m = hashlib.md5() with open(file_path, mode='rb') as f: f.seek(start_point) block = personal_config_info['BLOCK_SIZE'] total = rest_file_size num = 0 while rest_file_size: if rest_file_size > block: content = f.read(block) m.update(content) content = content.decode(self.coding) rest_file_size -= block num += block else: content = f.read(rest_file_size) m.update(content) content = content.decode(self.coding) rest_file_size -= rest_file_size num += rest_file_size FTP_pipe.sk_send_dic(sk, [content]) self.processBar(num, total) return m.hexdigest()
def myquit(self): dic = {'opt': 'exit'} FTP_pipe.sk_send_dic(self.sk, dic) exit()
def upload(self): ''' 步骤1:首先输入你要上传文件的路径 步骤2:通过文件路径获得上传文件的文件名、大小、服务器当前所在文件夹 步骤3:将文件名和文件大小传递到服务器,判断该文件是否已经存在,并判断是不是断点续传 步骤4:如果服务器文件存在重名文件---则判断大小 ·如果服务器文件大小要待上传的文件大小,则返回提示-->已经存在相同文件名, 不能上传,或者提示是否进行覆盖,或者将待上传文件在重命名为***(1)之后上传 ·如果服务器文件小于要待上传的文件大小,则返回提示--->断点续传 如果服务器文件不存在重名文件--则直接上传 :return: ''' upload_file_path = input('请输入要上传的文件路径>>>') self.file_size = os.path.getsize(upload_file_path) self.upload_file_name = upload_file_path.rstrip(os.sep).split( os.sep).pop() dic_info = { 'opt': 'upload', 'file_name': self.upload_file_name, 'current_path': self.current_path, 'root_path': self.root_path } FTP_pipe.sk_send_dic(self.sk, dic_info) #[False,server_file_size,server_file_md5] # [True] ret = FTP_pipe.sk_recv_dic(self.sk) if ret[0] == True: #在服务器完全重新上传的情况 dic_info = { 'opt': 'upload_from_null', 'upload_file_size': self.file_size } FTP_pipe.sk_send_dic(self.sk, dic_info) client_upload_file_md5 = self.file_send(self.sk, upload_file_path, self.file_size, 0) server_upload_file_md5 = FTP_pipe.sk_recv_dic(self.sk)[0] if client_upload_file_md5 == server_upload_file_md5: print('上传成功!') else: print('上传失败,请重新上传') return elif ret[0] == False: #在服务器需要断点续传的情况 server_file_size = ret[1] server_file_md5 = ret[2] rest_file_size = self.file_size - server_file_size dic_info = { 'opt': 'resume_breakpoint', 'rest_file_size': rest_file_size, 'start_position': server_file_size } FTP_pipe.sk_send_dic(self.sk, dic_info) client_upload_file_md5 = self.content_md5(upload_file_path, self.file_size) if server_file_size > self.file_size: print('服务器已经存在内容不同却名字相同而且比上传文件大的的文件!不能上传') elif server_file_size == self.file_size: if client_upload_file_md5 == server_file_md5: print('服务端存在两个完全一样的文件,不能上传!') else: print('服务端存在两个一样大小但内容不同的文件,不能上传!') elif server_file_size < self.file_size and (client_upload_file_md5 != server_file_md5): print('两个文件重名,服务器文件小,但是内容不一样,不能上传!') else: client_upload_file_md5 = self.content_md5( upload_file_path, server_file_size) if client_upload_file_md5 == ret[2]: order = input('是否需要断点续传(y/n)>>>') if order == 'y': client_upload_file_md5 = self.file_send( self.sk, upload_file_path, rest_file_size, server_file_size) server_rest_file_md5 = FTP_pipe.sk_recv_dic(self.sk)[0] if client_upload_file_md5 == server_rest_file_md5: print('断点续传成功!') else: return