作业:FTP
作业题目: 开发一个支持多用户在线的FTP程序
-
作业需求:
要求 1.用户加密认证(已实现) 2.允许同时多用户登录 3.每个用户有自己的家目录 ,且只能访问自己的家目录(已实现) 4.对用户进行磁盘配额,每个用户的可用空间不同 5.允许用户在ftp server上随意切换目录(已实现) 6.允许用户查看当前目录下文件(已实现) 7.允许上传和下载文件,保证文件一致性(md5)(已实现) 8.文件传输过程中显示进度条(已实现) 9.附加功能:支持文件的断点续传(已实现)
FTP实现实现并发,在main模块里进行修改,增加了mytherad.py
1.在之前开发的FTP基础上,开发支持多并发的功能 2.不能使用SocketServer模块,必须自己实现多线程 3.必须用到队列Queue模块,实现线程池 4.允许配置最大并发数,比如允许只有10个并发用户
C:.
│ RAMDE
│
│ __init__.py
│
├─ftpclient
│ ..bak
│ ..dat
│ ..dir
│ a.txt
│ client.py -- 客户端
│ __init__.py
│
└─ftpserver
│ __init__.py
│
├─bin
│ server.py ----- 启动文件
│ __init__.py
│
├─conf
│ │ account.ini ---- 用户数据
│ │ setting.py ----- 配置文件
│ │ __init__.py
│ │
│ └─__pycache__
│ setting.cpython-36.pyc
│ __init__.cpython-36.pyc
│
├─core
│ │ logger.py ---- 日志
│ │ main.py ----- 主程序
│ │ main_server.py --- 解析命令
│ │ mythread.py --- 实现线程,定义线程池
│ │
│ └─__pycache__
│ logger.cpython-36.pyc
│ main.cpython-36.pyc
│ main_server.cpython-36.pyc
│ __init__.cpython-36.pyc
│
├─home
│ │ __init__.py
│ │
│ └─alex ---- 主目录
│ a.txt
│
│
└─log --- 日志文件
注:需要在cmd上运行程序,否则会报错,服务端:python server.py start 客户端:python client.py -s ip地址 -P 端口
server.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 import os 4 import sys 5 6 7 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 sys.path.append(BASE_DIR) 9 10 if __name__ == '__main__': 11 from core import main_server 12 argv_parser = main_server.Mangement(sys.argv) 13 argv_parser.execute()
setting.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #! /usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 import os 4 import socket 5 import logging 6 7 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 HOME_DIR = os.path.join(BASE_DIR,'home') 9 ACCOUNT_INI = r'%s\conf\account.ini'% BASE_DIR 10 11 address_family = socket.AF_INET 12 socket_type = socket.SOCK_STREAM 13 max_packet_size = 8096 14 request_queue_size = 5 15 16 LOG_LEVE = logging.INFO 17 18 LOG_TYPE = { 19 'access':'access.log', 20 } 21 22 LOG_FORMATTER =logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 23 LOG_PATH = os.path.join(BASE_DIR,'log') 24 25 SERVER_ADDR = '127.0.0.1' 26 SERVER_PORT = 8080
logger.py
1 #!/usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 4 from conf import setting 5 import logging 6 import os 7 from logging import handlers 8 9 def logger_log(log_type): 10 log = logging.getLogger(log_type) 11 log.setLevel(setting.LOG_LEVE) 12 13 file_log = os.path.join(setting.LOG_PATH,setting.LOG_TYPE[log_type]) 14 fh = handlers.TimedRotatingFileHandler(file_log,when='D',interval=3,encoding='utf-8') 15 log.addHandler(fh) 16 17 file = setting.LOG_FORMATTER 18 fh.setFormatter(file) 19 return log
main.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 4 import socket 5 import json 6 import configparser 7 import hashlib 8 import struct 9 import os 10 import subprocess 11 import time 12 from conf import setting 13 from .logger import logger_log 14 from .mythread import Mythread 15 from threading import Thread 16 import queue 17 access_log = logger_log('access') 18 19 class Ftpserver: 20 STATUS_CODE ={ 21 200: "Passed authentication!", 22 201: "Wrong username or password!", 23 300: "File does not exist !", 24 301: "File exist , and this msg include the file size- !", 25 302: "This msg include the msg size!", 26 350: "Dir changed !", 27 351: "Dir doesn't exist !", 28 401: "File exist ,ready to re-send !", 29 402: "File exist ,but file size doesn't match!", 30 404: "File created successfully!", 31 405: "File deleted successfully!", 32 406: "File already exists!", 33 407: "File does not exist !", 34 500: 'Folder deletion succeeded!', 35 501: 'Folder does not exist!' 36 } 37 def __init__(self,mangement_instantiation): 38 self.mangement_instantiation = mangement_instantiation 39 self.socket = socket.socket(setting.address_family,setting.socket_type) 40 self.socket.bind((setting.SERVER_ADDR,setting.SERVER_PORT)) 41 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 42 self.socket.listen(setting.request_queue_size) 43 self.pool = Mythread(setting.THREAD_SIZE) 44 self.account = self.load_accuont() 45 self.user_obj = None 46 self.user_client = None 47 self.user_disk = None 48 self.username = None 49 50 51 52 def run(self): 53 '''启动FTP服务器''' 54 print('start FTPserver on %s:%s'.center(50,'*')%(setting.SERVER_ADDR,setting.SERVER_PORT)) 55 while True: 56 try: 57 request,self.addr = self.socket.accept() 58 # self.request = request 59 print('got ab new connection form %s...'%(self.addr,)) 60 t = self.pool.get_queue() 61 obj = t(target=self.handler,args=(request,)) 62 obj.start() 63 except Exception: 64 break 65 66 def load_accuont(self): 67 '''读取用户数据''' 68 config_obj = configparser.ConfigParser() 69 config_obj.read(setting.ACCOUNT_INI) 70 print(config_obj.sections()) 71 return config_obj 72 73 def authentication(self,username,password): 74 '''验证用户账户''' 75 if username in self.account: 76 _password = self.account[username]['password'] 77 md5_obj = hashlib.md5() 78 md5_obj.update(password.encode('utf-8')) 79 md5_password = md5_obj.hexdigest() 80 if md5_password == _password: 81 # print('登陆成功!') 82 self.user_obj = self.account[username] 83 self.user_obj['home'] = os.path.join(setting.HOME_DIR,username) 84 self.user_client = self.user_obj['home'] 85 self.user_disk = self.account[username]['file_disk'] 86 access_log.info('%s 成功登陆了FTP服务器,IP地址:%s,'%(username,self.addr)) 87 return True 88 else: 89 print('登陆失败') 90 access_log.error('%s 尝试登陆FTP服务器,IP地址:%s,'%(username,self.addr)) 91 return False 92 else: 93 print('登陆失败!') 94 access_log.error('%s 尝试登陆FTP服务器,IP地址:%s,' % (username, self.addr)) 95 return False 96 def handler(self,request): 97 '''处理用户交互''' 98 while True: 99 try: 100 raw_data = request.recv(4) 101 if not raw_data: 102 self.pool.put_queue() 103 data_size = struct.unpack('i',raw_data)[0] 104 data_bytes = request.recv(data_size) 105 data = json.loads(data_bytes.decode('utf-8')) 106 action_type = data.get('action_type') 107 if action_type: 108 if hasattr(self,'_%s'%action_type): 109 func = getattr(self,'_%s'%action_type) 110 func(data,request) 111 except Exception: 112 break 113 114 115 def send_response(self,status_code,*args,**kwargs): 116 '''发送消息给客户端''' 117 conn = args[0] 118 data = kwargs 119 data['status_code'] = status_code 120 data['status_msg'] = self.STATUS_CODE[status_code] 121 bytes_data = json.dumps(data).encode('utf-8') 122 data_struct = struct.pack('i',len(bytes_data)) 123 conn.send(data_struct) 124 conn.send(bytes_data) 125 126 def _auth(self,data,*args,**kwargs): 127 '''处理用户认证''' 128 conn = args[0] 129 if self.authentication(data.get('username'),data.get('password')): 130 print('登陆成功') 131 self.send_response(200,conn) 132 else: 133 self.send_response(201,conn) 134 135 def _get(self,data,*args): 136 '''接收客户端下载''' 137 conn = args[0] 138 filename = data.get('filename') 139 full_path = os.path.join(self.user_client,filename) 140 if os.path.isfile(full_path): 141 file_size = os.stat(full_path).st_size 142 self.send_response(301,conn,file_size=file_size) 143 print('准备发送!') 144 with open(full_path,'rb') as f: 145 for line in f: 146 conn.send(line) 147 else: 148 print('文件发送成功') 149 access_log.info('%s 下载了文件%s,IP地址:%s,'% (self.user_obj['username'],filename,self.addr)) 150 else: 151 self.send_response(300,conn) 152 access_log.info('%s 下载文件%s失败,IP地址:%s,' % (self.user_obj['username'],filename,self.addr)) 153 154 def _put(self,data,*args): 155 conn = args[0] 156 filename = data.get('filename') 157 full_path = os.path.join(self.user_client, filename) 158 if os.path.isfile(full_path): 159 filename = '%s.%s'%(full_path,time.time()) 160 else: 161 filename = full_path 162 with open(filename,'wb') as f: 163 total_size = data.get('file_size') 164 recv_size = 0 165 while recv_size < total_size: 166 recv_data = conn.recv(1024) 167 f.write(recv_data) 168 recv_size += len(recv_data) 169 print('总大小:%s,已接收:%s'%(total_size,recv_size)) 170 else: 171 print('接收成功') 172 access_log.info('%s 上传了文件%s,IP地址:%s,' % (self.user_obj['username'], filename,self.addr)) 173 174 def _ls(self,data,*args): 175 '''查看''' 176 conn = args[0] 177 cmd_obj = subprocess.Popen('dir %s'%self.user_client,shell=True, 178 stdout=subprocess.PIPE, 179 stderr=subprocess.PIPE) 180 stdout = cmd_obj.stdout.read() 181 stderr = cmd_obj.stderr.read() 182 request = stdout + stderr 183 if not request: 184 request = bytes('此目录无文件!') 185 self.send_response(302,conn,cmd_size=len(request)) 186 conn.sendall(request) 187 188 def _mkdir(self,data,*args): 189 '''创建文件夹''' 190 conn = args[0] 191 filename = data.get('inp') 192 full_path = os.path.abspath(os.path.join(self.user_client,filename)) 193 cmd_obj = subprocess.Popen('mkdir %s'%(full_path),shell=True, 194 stdout=subprocess.PIPE, 195 stderr=subprocess.PIPE) 196 stdout = cmd_obj.stdout.read() 197 stderr = cmd_obj.stderr.read() 198 request = stderr + stdout 199 if request: 200 self.send_response(406,conn) 201 self.send_response(404,conn,cmd_mkdir=len(request)) 202 conn.sendall(request) 203 access_log.info('%s 成功创建文件%s,IP地址:%s,' % (self.user_obj['username'],filename,self.addr)) 204 def _del(self,data,*args): 205 '''删除文件''' 206 conn = args[0] 207 del_name = data.get('del_name') 208 full_path = os.path.abspath(os.path.join(self.user_client,del_name)) 209 cmd_obj = subprocess.Popen('del %s'%(full_path),shell=True, 210 stdout=subprocess.PIPE, 211 stderr=subprocess.PIPE) 212 stdout = cmd_obj.stdout.read() 213 stderr = cmd_obj.stderr.read() 214 request = stderr + stdout 215 if not request: 216 self.send_response(407,conn) 217 self.send_response(405,conn,del_mkdir=len(request)) 218 conn.sendall(request) 219 access_log.info('%s 成功删除文件%s,IP地址:%s,' % (self.user_obj['username'], del_name, self.addr)) 220 221 def _rm(self,data,*args): 222 '''删除文件夹''' 223 conn = args[0] 224 rm_name = data.get('rm_name') 225 full_path = os.path.abspath(os.path.join(self.user_client,rm_name)) 226 cmd_obj = subprocess.Popen('rd %s'%(full_path),shell=True, 227 stdout=subprocess.PIPE, 228 stderr=subprocess.PIPE) 229 stdout = cmd_obj.stdout.read() 230 stderr = cmd_obj.stderr.read() 231 request = stderr + stdout 232 if not request: 233 self.send_response(501,conn) 234 self.send_response(500,conn,rm_mkdir=len(request)) 235 conn.sendall(request) 236 access_log.info('%s 成功删除文件%s,IP地址:%s,' % (self.user_obj['username'], rm_name, self.addr)) 237 238 def _cd(self,data,*args): 239 '''切换目录''' 240 conn = args[0] 241 target = data.get('target_dir') 242 full_path = os.path.abspath(os.path.join(self.user_client,target)) 243 if os.path.isdir(full_path): 244 if full_path.startswith(self.user_obj['home']): 245 self.user_client = full_path 246 relative_dir = self.user_client.replace(self.user_obj['home'],'') 247 self.send_response(350,conn,current_dir=relative_dir) 248 else: 249 self.send_response(351,conn) 250 else: 251 self.send_response(351,conn) 252 253 def _re_get(self,data,*args): 254 conn = args[0] 255 filename = data.get('filename') 256 file_size = data.get('file_size') 257 full_path = os.path.join(self.user_client,filename.strip('\\')) 258 if os.path.isfile(full_path): 259 if os.path.getsize(full_path) == file_size: 260 self.send_response(401,filename=filename) 261 with open(full_path,'rb') as f: 262 f.seek(data.get('recveived_size')) 263 for line in f: 264 conn.send(line) 265 else: 266 print('发送完毕!') 267 else: 268 self.send_response(402,conn) 269 else: 270 self.send_response(300,conn)
main_server.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 4 from .main import Ftpserver 5 6 class Mangement: 7 8 def __init__(self,sys_argv): 9 '''解析指令,调用相应的模块''' 10 self.sys_argv = sys_argv 11 print(sys_argv) 12 self.verify_argv() 13 14 def verify_argv(self): 15 '''验证指令是否合法''' 16 if len(self.sys_argv) <2: 17 self.help_msg() 18 cmd = self.sys_argv[1] 19 if not hasattr(self,cmd): 20 print('输入错误!') 21 self.help_msg() 22 23 def help_msg(self): 24 msg = ''' 25 start start FTP server 26 stop stop FTP server 27 restart restart FTP server 28 ''' 29 exit(msg) 30 31 def execute(self): 32 cmd = self.sys_argv[1] 33 func = getattr(self,cmd) 34 func() 35 36 def start(self): 37 server = Ftpserver(self) 38 server.run_forever()
client.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 4 import socket 5 import struct 6 import os 7 import json 8 import optparse 9 import shelve 10 11 class Myclient: 12 def __init__(self): 13 self.username = None 14 self.terminal_dis = None 15 self.current_dir = None 16 self.shelve_obj = shelve.open('.') 17 parser = optparse.OptionParser() 18 parser.add_option("-s","--server", dest="server", help="ftp server ip_addr") 19 parser.add_option("-P","--port",type="int", dest="port", help="ftp server port") 20 parser.add_option("-u","--username", dest="username", help="username info") 21 parser.add_option("-p","--password", dest="password", help="password info") 22 self.options , self.args = parser.parse_args() 23 self.arvs_verify() 24 self.make_connt() 25 26 def arvs_verify(self): 27 '''检查命令的合法性''' 28 if not self.options.server or not self.options.port: 29 print('缺少必要的参数!') 30 31 def make_connt(self): 32 '''建立链接''' 33 self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 34 self.sock.connect((self.options.server,self.options.port)) 35 36 def get_response(self): 37 data = self.sock.recv(4) 38 hear_size = struct.unpack('i',data)[0] 39 hear_bytes = self.sock.recv(hear_size) 40 hear_dic = json.loads(hear_bytes) 41 return hear_dic 42 43 def auth(self): 44 count = 0 45 while count < 3: 46 username = input('请输入账号:').strip() 47 password = input('请输入密码:').strip() 48 auth_info = { 49 'action_type':'auth', 50 'username':username, 51 'password':password, 52 } 53 hear_json = json.dumps(auth_info) 54 hear_bytes = hear_json.encode('utf-8') 55 self.sock.send(struct.pack('i', len(hear_bytes))) 56 self.sock.send(hear_bytes) 57 response = self.get_response() 58 if response.get('status_code') == 200: 59 self.username = username 60 self.terminal_dis = '[%s]>>'%self.username 61 self.current_dir = '\\' 62 print('登陆成功!') 63 msg = ''' 64 del 删除文件 65 ls 查看当前文件 66 cd 切换目录 67 mkdir 创建文件夹 68 put 上传文件 69 get 下载文件 70 rm 删除文件夹 71 ''' 72 print(msg) 73 return True 74 else: 75 print(response.get('status_msg')) 76 count += 1 77 78 def file_check(self): 79 if list(self.shelve_obj.keys()): 80 print('未下载成功的列表'.center(50,'*')) 81 for index,abs_file in enumerate(self.shelve_obj.keys()): 82 print(self.shelve_obj[abs_file][1]) 83 recv_size = os.path.getsize(self.shelve_obj[abs_file][1]) 84 print(' %s.%s %s %s %s'%(index,abs_file, 85 self.shelve_obj[abs_file][0], 86 recv_size, 87 recv_size/self.shelve_obj[abs_file][0]*100)) 88 89 while True: 90 choice = input('请选择继续下载的文件:').strip() 91 if not choice:continue 92 if choice == 'back':break 93 if choice.isdigit(): 94 choice = int(choice) 95 if choice >=0 and choice <= index: 96 selected_file = list(self.shelve_obj.keys())[choice] 97 already_rec_size = os.path.getsize(self.shelve_obj[selected_file][1]) 98 self.send_msg('re_get',file_size=self.shelve_obj[selected_file][0], 99 filename=selected_file, 100 recveived_size=already_rec_size) 101 response = self.get_response() 102 new_filename = response.get('filename').strip('\\') 103 if response.get('status_code') == 401: 104 local_filename = self.shelve_obj[selected_file][1] 105 with open(local_filename,'ab') as f: 106 total_size = self.shelve_obj[selected_file][0] 107 recv_size = already_rec_size 108 current_percent = int(recv_size / total_size * 100) 109 progress_generator = self.progress_bar(total_size, 110 current_percent,current_percent) 111 progress_generator.__next__() 112 while recv_size < total_size: 113 res = self.sock.recv(1024) 114 f.write(res) 115 recv_size += len(res) 116 progress_generator.send(recv_size) 117 else: 118 print('下载完毕') 119 del self.shelve_obj[selected_file] 120 os.rename(local_filename, new_filename) 121 122 else: 123 print(response.get('status_msg')) 124 125 126 127 def interactive(self): 128 if self.auth(): 129 self.file_check() 130 while True: 131 user_input = input(self.terminal_dis).strip() 132 if not user_input:continue 133 cmd_list = user_input.split() 134 if hasattr(self,'_%s'%cmd_list[0]): 135 func = getattr(self,'_%s'%cmd_list[0]) 136 func(cmd_list[1:]) 137 138 139 def send_msg(self,acttion_type,*args,**kwargs): 140 '''将消息发送到远程''' 141 my_data = { 142 'action_type':acttion_type 143 144 } 145 my_data.update(kwargs) 146 hear_json = json.dumps(my_data) 147 hear_bytes = hear_json.encode('utf-8') 148 self.sock.send(struct.pack('i',len(hear_bytes))) 149 self.sock.send(hear_bytes) 150 151 def parameter_check(self, args, min_args=None, max_args=None, exact_args=None): 152 """参数个数合法性检查""" 153 if min_args: 154 if len(args) < min_args: 155 print("must provide at least %s parameters but %s received." %(min_args,len(args))) 156 return False 157 if max_args: 158 if len(args) > max_args: 159 print("need at most %s parameters but %s received." %(max_args,len(args))) 160 return False 161 if exact_args: 162 if len(args) != exact_args: 163 print("need exactly %s parameters but %s received." % (exact_args, len(args))) 164 return False 165 return True 166 167 def progress_bar(self,total_size,current_percent=0,last_percent=0): 168 '''进度条''' 169 while True: 170 received_size = yield current_percent 171 current_percent = int(received_size /total_size * 100) 172 if current_percent > last_percent: 173 print('>' * int(current_percent / 2) + '{percnet}%'.format(percnet=current_percent),end='\r', 174 flush=True) 175 last_percent = current_percent 176 177 def _get(self,cmd_argv): 178 '''下载文件''' 179 if self.parameter_check(cmd_argv,min_args=1): 180 filename = cmd_argv[0] 181 self.send_msg(acttion_type='get',filename=filename) 182 response = self.get_response() 183 if response.get('status_code') == 301: 184 file_size = response.get('file_size') 185 recv_size = 0 186 progress_gen = self.progress_bar(file_size) 187 progress_gen.__next__() 188 189 file_abs_path = os.path.join(self.current_dir,filename) 190 self.shelve_obj[file_abs_path] = [file_size,'%s.download'%filename] 191 192 with open('%s.download'%filename,'wb') as f: 193 while recv_size < file_size: 194 res = self.sock.recv(1024) 195 recv_size += len(res) 196 f.write(res) 197 progress_gen.send(recv_size) 198 else: 199 print('\n') 200 print('下载成功!') 201 del self.shelve_obj[file_abs_path] 202 os.rename('%s.download'%filename,filename) 203 else: 204 print(response.get('status_msg')) 205 206 207 208 209 def _put(self,cmd_argv): 210 '''上传文件''' 211 if self.parameter_check(cmd_argv,exact_args=1): 212 filename = cmd_argv[0] 213 if os.path.isfile(filename): 214 file_size = os.path.getsize(filename) 215 self.send_msg(acttion_type='put',file_size=file_size,filename=filename) 216 print('准备发送') 217 send_size = 0 218 progress_gen = self.progress_bar(file_size) 219 progress_gen.__next__() 220 with open(filename,'rb') as f: 221 for line in f: 222 self.sock.send(line) 223 send_size += len(line) 224 progress_gen.send(send_size) 225 226 else: 227 print('\n') 228 print('上传成功!') 229 230 231 def _ls(self,cmd_argv): 232 '''查看''' 233 self.send_msg(acttion_type='ls') 234 response = self.get_response() 235 if response.get('status_code') == 302: 236 cmd_size = response.get('cmd_size') 237 recv_size = 0 238 cmd_result = b'' 239 while recv_size < cmd_size: 240 res = self.sock.recv(1024) 241 cmd_result += res 242 recv_size += len(res) 243 else: 244 print(cmd_result.decode('gbk')) 245 246 247 def _mkdir(self,cmd_argv): 248 '''创建文件夹''' 249 if self.parameter_check(cmd_argv,exact_args=1): 250 inp = cmd_argv[0] 251 self.send_msg(acttion_type='mkdir',inp=inp) 252 response = self.get_response() 253 if response.get('status_code') == 404: 254 print(response.get('status_msg')) 255 elif response.get('status_code') == 406: 256 print(response.get('status_msg')) 257 258 def _del(self,cmd_argv): 259 '''删除文件''' 260 if self.parameter_check(cmd_argv,exact_args=1): 261 del_name = cmd_argv[0] 262 self.send_msg(acttion_type='del',del_name=del_name) 263 response = self.get_response() 264 if response.get('status_code') == 405: 265 print(response.get('status_msg')) 266 elif response.get('status_code') == 407: 267 print(response.get('status_msg')) 268 269 def _rm(self,cmd_argv): 270 '''删除文件夹''' 271 if self.parameter_check(cmd_argv,exact_args=1): 272 rm_name = cmd_argv[0] 273 self.send_msg(acttion_type='rm',rm_name=rm_name) 274 response = self.get_response() 275 if response.get('status_code') == 500: 276 print(response.get('status_msg')) 277 elif response.get('status_code') == 501: 278 print(response.get('status_msg')) 279 280 def _cd(self,cmd_argv): 281 '''切换目录''' 282 if self.parameter_check(cmd_argv,exact_args=1): 283 target_dir = cmd_argv[0] 284 self.send_msg(acttion_type='cd',target_dir=target_dir) 285 response = self.get_response() 286 if response.get('status_code') == 350: 287 self.terminal_dis = '[[%s]>>\%s]'% (self.username,response.get('current_dir')) 288 self.current_dir = response.get('current_dir') 289 290 291 292 293 294 if __name__ == '__main__': 295 obj = Myclient() 296 obj.interactive()
mythread.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 from threading import Thread 4 import queue 5 6 class Mythread: 7 '''自定义线程池,实现并发''' 8 def __init__(self,maxsize): 9 self.maxsize = maxsize 10 self.q = queue.Queue(maxsize) # 初始一个队列对象 11 for i in range(maxsize): 12 self.q.put(Thread) # 在队列对象中先存放线程对象 13 14 def get_queue(self): 15 '''从队列中取出线程对象''' 16 return self.q.get() 17 18 def put_queue(self): 19 '''往队列存放线程对象''' 20 return self.q.put(Thread)