python: 基于select的sokct ftp 客户端
#7512 import socket import hashlib,time import json import sys,os import random BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from conf import setting import signal # 切换工作目录 # def exit_handle(signum, frame): # # savedict,addr = client.get_save() # print("dddd",savedict,addr) # if addr: # with open(addr + '\\%s'%savedict["user"], 'wb') as f: # f.write(json.dumps(savedict).encode()) # print(''' # ******************************* # 暂 停 # ******************************* # ''') # exit() # # signal.signal(signal.SIGINT,exit_handle) # signal.signal(signal.SIGTERM,exit_handle) class selectFTPClient(object): ''' FTP客户端 ''' SOCK_FAMALY = socket.AF_INET # IP v4 SOCK_TYPE = socket.SOCK_STREAM SOCK_ALLOW_CONN = 1024 def __init__(self,ip = 'localhost' ,port = 9999): self.client = socket.socket(self.SOCK_FAMALY,self.SOCK_TYPE) try: self.client.connect((ip,port)) self.msg_dict = {} print("登陆时间:[%s],主机地址:[%s]"%(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()),self.client.getpeername())) self.interrupt = False self.interaction() except ConnectionRefusedError as e: print('\033[31;1m 连接中断,中断原因 [%s] ,中断时间:[%s] \033[0m' % (e, time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()))) self.client.close() def com_get(self,com): os.chdir(setting.CLIENT_HOME) self.client.send(self.datahead(com, 'send')) recv_data = self.client.recv(1024) recv_data = self.datahead(recv_data,'recv') if recv_data['error'] == 777: filesize = recv_data['size'] file_recv = 0 _md5 = hashlib.md5() file_obj = open('copy%d'%random.randint(1,10000),'wb') respond = self.datahead(self.com_handle('rspond_ok'),'send') self.client.send(respond) print(recv_data) while file_recv < filesize: if filesize - file_recv > 1024 : size = 1024 else: size = filesize - file_recv data = self.client.recv(size) file_recv +=len(data) file_obj.write(data) file_obj.flush() _md5.update(data) percentage = float(file_recv / filesize) * 100 print("%.2f"%percentage) else: file_obj.close() md5 = self.client.recv(size).decode() if md5 == _md5.hexdigest(): print('\033[32;1m 下载成功 ,时间:[%s] \033[0m' % (time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()))) else: print('\033[31;1m 文件传输过程中丢失数据! ,时间:[%s] \033[0m' % (time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()))) else: print('\033[31;1m 文件不存在,请重新输入! \033[0m') self.interaction() def com_put(self,com): os.chdir(setting.CLIENT_HOME) if os.path.exists(com['filename']): if os.path.isfile(com['filename']): com['size'] = os.stat(com['filename']).st_size com['error'] = 777 else: print('\033[31;1m 文件不存在,请重新输入! \033[0m') self.interaction() self.client.send(self.datahead(com,'send')) recv_data = self.client.recv(1024) print(recv_data) if recv_data == b'rspond_ok': file_obj=open(com['filename'],'rb') for line in file_obj: self.client.send(line) time.sleep(1) print(1) print("上传完毕") # # if recv_data == b'rspond_ok': # # recv_data = self.datahead(recv_data, 'recv') # send_data = {} # com = com.strip().split() # send_data['error'] = 222; # send_data['action'] = com[0] # if os.path.exists(com[1]): # if os.path.isfile(com[1]): # send_data['size'] = os.stat(com[1]).st_size # send_data['error'] = 777; # send_data['filename'] = com[1]; # print(send_data) # _send ='upload'+' '+ json.dumps(send_data) # self.client.send(_send.encode()) # recv_data = self.client.recv(1024) # recv_data = self.datahead(recv_data, 'recv') def com_format(self,com_data): pass def interaction(self): while True: try: com = input("%s>>:"%setting.CLIENT_HOME) if len(com) == 0: continue com = self.com_handle(com) antion = com['action'] print(com) if antion is not None and hasattr(self, 'com_%s' % antion ): func = getattr(self, 'com_%s' % antion) func(com) else: continue except (ConnectionRefusedError,ConnectionResetError )as e: print('\033[31;1m 连接中断,中断原因 [%s] ,中断时间:[%s] \033[0m' % (e, time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime()))) self.client.close() def com_handle(self,com): com = com.strip().split() com_dict ={} if len(com) > 1 : com_dict['action'] = com[0] com_dict['filename'] =com[1] else: com_dict['action'] = com[0] com_dict['filename'] = 'no' com_dict['size'] = 0 com_dict['error'] = 222 return com_dict def datahead(self,data,flag = 'else'): if flag == 'send': return json.dumps(data).encode() elif flag == 'recv': return json.loads(data.decode()) else: return data.encode() if __name__ == '__main__': client = selectFTPClient()