![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7f7c578260aa102d40b70fa1f9fe4a7c.png)
import optparse,socket,json,os,sys
STATUS_CODE={
250:"invalid cmd format",
251:"invalid cmd",
252:"invalid auth data",
253:"wrong username or pwd",
254:"passed authentication",
255:"filename doesn't provided",
256:"file doesn't exist",
257:"ready to send file",
258:"md5 verification",
800:"the file exist,but not enough",
801:"the file exist",
802:"ready to receive data",
900:"md5 valdate success"
}
class ClientHandler():
def __init__(self):
self.op=optparse.OptionParser()
self.op.add_option("-s","--server",dest="server")
self.op.add_option("-P", "--port", dest="port")
self.op.add_option("-u", "--username", dest="username")
self.op.add_option("-p", "--pwd", dest="pwd")
self.options,self.args=self.op.parse_args()
self.verify_args(self.options,self.args)
self.make_connection()
self.mainPath=os.path.dirname(os.path.abspath(__file__))
self.last=0
def verify_args(self,options,args):
server=options.server
port=options.port
username=options.username
pwd=options.pwd
if int(port)>0 and int(port)<65535:
return True
else:
exit("The port should in (0,65535)")
def make_connection(self):
self.sock=socket.socket()
self.sock.connect((self.options.server,int(self.options.port)))
def interactive(self):
print("begin")
if self.authenticate():
while True:
cmd_info=input("[%s]"%self.current_dir).strip()
cmd_list=cmd_info.split()
if hasattr(self,cmd_list[0]):
func=getattr(self,cmd_list[0])
func(*cmd_list)
def put(self,*cmd_list):
action,local_path,target_path=cmd_list
local_path=os.path.join(self.mainPath,local_path)
filename=os.path.basename(local_path)
file_size=os.stat(local_path).st_size
data={"action":"put","filename":filename,"file_size":file_size,"target_path":target_path}
self.sock.send(json.dumps(data).encode("utf-8"))
is_exist=int(self.sock.recv(1024).decode("utf-8"))
has_sent=0
if is_exist==800:
choice=input("the file exist,but is not complete,continue or not?[Y/N]").strip()
if choice=="Y" or choice=="y":
self.sock.sendall("Y".encode("utf-8"))
continue_position=int(self.sock.recv(1024))
has_sent+=continue_position
else:
self.sock.sendall("N".encode("utf-8"))
elif is_exist==801:
print("the file exist")
return "OK"
elif is_exist==802:
pass
f=open(local_path,"rb")
f.seek(has_sent)
while has_sent<file_size:
data=f.read(1024)
self.sock.sendall(data)
has_sent+=len(data)
self.show_progress(has_sent,file_size)
f.close()
print("upload succeed")
def authenticate(self):
if self.options.username is None or self.options.pwd is None:
username=input("username:")
pwd=input("password:")
return self.get_auth_result(username,pwd)
return self.get_auth_result(self.options.username,self.options.pwd)
def response(self):
data=self.sock.recv(1024).decode("utf-8")
data=json.loads(data)
return data
def get_auth_result(self,user,pwd):
data={"action":"auth","username":user,"pwd":int(pwd)}
self.sock.send(json.dumps(data).encode("utf-8"))
response=self.response()
if response["status_code"]==254:
self.user=user
self.current_dir=user
print(STATUS_CODE[254])
return True
else:
print(STATUS_CODE[response["status_code"]])
def show_progress(self,has,total):
rate=float(has)/float(total)
rate_num=int(rate*100)
sys.stdout.write("%s%% %s\r"%(rate_num,"#"*rate_num))
self.last=rate_num
def ls(self,*cmd_list):
data={"action":"ls"}
self.sock.sendall(json.dumps(data).encode("utf-8"))
result=self.sock.recv(1024).decode("utf-8")
print(result)
def cd(self,*cmd_list):
data={"action":"cd","dirname":cmd_list[1]}
self.sock.sendall(json.dumps(data).encode("utf-8"))
result=self.sock.recv(1024).decode("utf-8")
self.current_dir=os.path.basename(result)
def mkdir(self,*cmd_list):
data={"action":"mkdir","dirname":cmd_list[1]}
self.sock.sendall(json.dumps(data).encode("utf-8"))
result=self.sock.recv(1024).decode("utf-8")
print(result)
ch=ClientHandler()
ch.interactive()
import os,sys
PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(PATH)
from core import main
if __name__=="__main__":
print("FTP_Server start")
main.ArgvHandler()
import os,sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
IP="127.0.0.1"
PORT=8080
ACCOUNT_PATH=os.path.join(BASE_DIR,"conf","accounts.cfg")
[DEFAULT]
[root]
Password=123
Quotation=100
[han]
Password=111
Quotation=101
import optparse,socketserver
from conf import settings
from core import server
class ArgvHandler():
def __init__(self):
self.op=optparse.OptionParser()
options,args=self.op.parse_args()
self.verify_args(options,args)
def verify_args(self,options,args):
cmd=args[0]
if hasattr(self,cmd):
func=getattr(self,cmd)
func()
def start(self):
s=socketserver.ThreadingTCPServer((settings.IP,settings.PORT),server.ServerHandler)
s.serve_forever()
def help(self):
pass
import socketserver,json,configparser,os
from conf import settings
STATUS_CODE={
250:"invalid cmd format",
251:"invalid cmd",
252:"invalid auth data",
253:"wrong username or pwd",
254:"passed authentication",
255:"filename doesn't provided",
256:"file doesn't exist",
257:"ready to send file",
258:"md5 verification",
800:"the file exist,but not enough",
801:"the file exist",
802:"ready to receive data",
900:"md5 valdate success"
}
class ServerHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
data=self.request.recv(1024).strip()
data=json.loads(data.decode("utf-8"))
if data.get("action"):
if hasattr(self,data.get("action")):
func=getattr(self,data.get("action"))
func(**data)
else:
print("No such command")
else:
print("Invalid command")
def send_response(self,state_code):
response={"status_code":state_code}
self.request.sendall(json.dumps(response).encode("utf-8"))
def auth(self,**data):
username=data["username"]
pwd=data["pwd"]
user=self.authenticate(username,pwd)
if user:
self.send_response(254)
else:
self.send_response(253)
def put(self,**data):
filename=data.get("filename")
file_size=data.get("file_size")
target_path=data.get("target_path")
abs_path=os.path.join(self.mainPath,target_path,filename)
has_received=0
if os.path.exists(abs_path):
file_has_size=os.stat(abs_path).st_size
if file_has_size<file_size:
self.request.sendall("800".encode("utf-8"))
choice=self.request.recv(1024).decode("utf-8")
if choice=="Y":
self.request.sendall(str(file_has_size).encode("utf-8"))
has_received+=file_has_size
f=open(abs_path,"ab")
else:
f = open(abs_path,"wb")
else:
self.request.sendall("801".encode("utf-8"))
return "OK"
else:
print(802)
self.request.sendall("802".encode("utf-8"))
f=open(abs_path,"wb")
while has_received<file_size:
try:
data=self.request.recv(1024)
f.write(data)
has_received+=len(data)
except Exception as e:
print(e)
break
f.close()
print("upload succeed")
def authenticate(self,user,pwd):
cfg=configparser.ConfigParser()
cfg.read(settings.ACCOUNT_PATH)
if user in cfg.sections():
if int(cfg[user]["Password"])==pwd:
self.user=user
self.mainPath=os.path.join(settings.BASE_DIR,"home",self.user)
return user
def ls(self,**data):
file_list=os.listdir(self.mainPath)
file_string="\n".join(file_list)
if not len(file_string):
file_string="no file or package"
self.request.sendall(file_string.encode("utf-8"))
def cd(self,**data):
dirname=data.get("dirname")
if dirname=="..":
self.mainPath=os.path.dirname(self.mainPath)
else:
self.mainPath=os.path.join(self.mainPath,dirname)
self.request.sendall(self.mainPath.encode("utf-8"))
def mkdir(self,**data):
dirname=data.get("dirname")
path=os.path.join(self.mainPath,dirname)
if not os.path.exists(path):
if "/" in dirname:
os.makedirs(path)
else:
os.mkdir(path)
self.request.sendall(("create %s successfully"%dirname).encode("utf-8"))
else:
self.request.sendall("dir exist already".encode("utf-8"))