python23-PTF更新版

fftp_client.py

import optparse
import socket
import json
import os
import sys
STATUS_CODE  = {
    250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
    251 : "Invalid cmd ",
    252 : "Invalid auth data",
    253 : "Wrong username or password",
    254 : "Passed authentication",
    255 : "Filename doesn't provided",
    256 : "File doesn't exist on server",
    257 : "ready to send file",
    258 : "md5 verification",

    800 : "the file exist,but not enough ,is continue? ",
    801 : "the file exist !",
    802 : " ready to receive datas",

    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','--p',dest='port')
        self.op.add_option('-u', '--username', dest='username')
        self.op.add_option('-p', '--password', dest='password')

        self.options,self.args = self.op.parse_args()
        #对端口和ip地址进行安全校验
        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
        # password=options.password
        if int(port)>0 and int(port)<65535:
            return True
        else:
            exit('the port is in 0-65535')

    def make_connection(self):
        self.sock=socket.socket()
        self.sock.connect((self.options.server,int(self.options.port)))
    #和服务端进行交互
    def interactive(self):
        if self.authenticate():
            print('begin to interactive........')
            cmd_info = input('[%s]'%self.current_dir).strip()#put 12png images
            cmd_list = cmd_info.split()
            if hasattr(self,cmd_list[0]):
                func=getattr(self,cmd_list[0])
                func(*cmd_list)
            else:
                print("Invalid cmd")
    #上传文件
    def put(self,*cmd_list):
        #put 12.png images
        action,local_path,target_path=cmd_list
        local_path=os.path.join(self.mainPath,local_path)

        file_name = os.path.basename(local_path)
        file_size=os.stat(local_path).st_size

        data={
            'action':'put',
            'file_name':file_name,
            'target_path':target_path
        }
        self.sock.send(json.dumps(data).encode('utf8'))

        is_exist=self.sock.recv(1024).decode('utf8')
        has_sent=0
        if is_exist=='800':
            #文件不完整
            choice=input('is continue?[Y/N]').strip()
            if choice.upper()=='Y':
                self.sock.sendall('Y'.encode('utf8'))
                continue_position=self.sock.recv(1024).decode('utf8')
                has_sent+=int(continue_position)
            else:
                self.sock.sendall('N'.encode('utf8'))
        elif is_exist=='801':
            #文件完全存在
            return

        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('put success!')

    #进度条
    def show_progress(self,has,total):
        rate=float(has)/float(total)
        rate_num=int(rate*100)
        if self.last!=rate_num:
            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('utf8'))
        data = self.sock.recv(1024).decode('utf8')
        print(data)

    def cd(self,*cmd_list):
        #cd images
        data={
            'action':'cd',
            'dirname':cmd_list[1]
        }
        self.sock.sendall(json.dumps(data).encode('utf8'))
        data = self.sock.recv(1024).decode('utf8')
        self.current_dir=os.path.basename(data)
    #创建文件夹
    def mkdir(self,*cmd_list):
        data={
            'action':'mkdir',
            'dirname':cmd_list[1]
        }
        self.sock.sendall(json.dumps(data).encode('utf8'))
        data = self.sock.recv(1024).decode('utf8')

    def authenticate(self):
        if self.options.username is None or self.options.password is None:
            username = input('username:')
            password = input('password:')
            return self.getauth_result(username,password)
        return self.getauth_result(self.options.username,self.options.password)

    def respones(self):
        data = self.sock.recv(1024).decode('utf8')
        data = json.loads(data)
        return data

    def getauth_result(self,user,pwd):
        data = {
            'action':'auth',
            'username':user,
            'password':pwd
        }
        self.sock.send(json.dumps(data).encode('utf8'))
        response=self.respones()
        print('response:',response['state_code'])
        if response['state_code']==254:
            self.user = user
            self.current_dir=user
            print(STATUS_CODE[254])
            return True
        else:
            print(STATUS_CODE[response['state_code']])



ch = ClientHandler()
#交互
ch.interactive()
复制代码

server.py

import configparser
import socketserver
import json
from conf import settings
import os
STATUS_CODE  = {
    250 : "Invalid cmd format, e.g: {'action':'get','filename':'test.py','size':344}",
    251 : "Invalid cmd ",
    252 : "Invalid auth data",
    253 : "Wrong username or password",
    254 : "Passed authentication",
    255 : "Filename doesn't provided",
    256 : "File doesn't exist on server",
    257 : "ready to send file",
    258 : "md5 verification",

    800 : "the file exist,but not enough ,is continue? ",
    801 : "the file exist !",
    802 : " ready to receive datas",

    900 : "md5 valdate success"

}

class ServerHandle(socketserver.BaseRequestHandler):
    def handle(self):
        while 1 :
            data = self.request.recv(1024).strip()
            data = json.loads(data.decode('utf8'))

            if data.get('action'):
                if hasattr(self,data.get('action')):
                    func = getattr(self,data.get('action'))
                    func(**data)
                else:
                    print('error')
            else:
                print('error')
    def send_response(self,state_code):
        response={'state_code':state_code,}
        self.request.sendall(json.dumps(response).encode('utf8'))

    def auth(self,**data):
        username=data['username']
        password=data['password']
        user = self.authenticate(username,password)
        if user :
            self.send_response(254)
        else:
            self.send_response(253)

    def authenticate(self,user,pwd):
        cfg=configparser.ConfigParser()
        cfg.read(settings.ACCOUNT_PATH)

        if user in cfg.sections():
            if cfg[user]['Password']==pwd:
                self.user = user
                self.mainPath=os.path.join(settings.BASE_DIR,'home',self.user)
                print('登录成功!')
                return user
    #上传文件
    def put(self,**data):
        print('data',data)
        file_name=data.get('file_name')
        file_size=data.get('file_size')
        target_path=data.get('target_path')

        abs_path=os.path.join(self.mainPath,target_path,file_name)

       #####################
        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('utf8'))
                choice=self.request.recv(1024).decode('utf8')
                if choice=='Y':
                    self.request.sendall(str(file_has_size).encode('utf8'))
                    has_received=file_has_size
                    f=open(abs_path,'ab')
                else:
                    f=open(abs_path,'wb')
            else:
                #完整
                self.request.sendall('801'.encode('utf8'))
                return
        else:
            self.request.sendall('802'.encode('utf8'))
            f = open(abs_path, 'wb')

        while has_received<file_size:
            try:
                data = self.request.recv(1024)
            except Exception as e:
                break
            f.write(data)
            has_received+=len(data)

        f.close()
    #查看文件下的目录
    def ls(self,**data):
        file_list=os.listdir(self.mainPath)
        file_str = '\n'.join(file_list)
        if not len(file_list):
            file_str='<empty dir>'
        self.request.sendall(file_str.encode('utf8'))
    #切换目录
    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('utf8'))
    #创建文件夹
    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 success'.encode('utf8'))
        else:
            self.request.sendall('dirname exist'.encode('utf8'))


复制代码

setting.py

import os
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')
复制代码

ftp_server.py

import os,sys
PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(PATH)
# print(PATH)
# print(sys.path)
# print(os.path.dirname(os.path.abspath(__file__)))
# print(os.path.abspath(__file__))

from core import main

if __name__ == '__main__':
    main.ArgvHandler()
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值