设为首页 加入收藏

TOP

用 Python实现一个ftp+CRT(不用ftplib)(一)
2017-09-30 16:22:23 】 浏览:603
Tags:Python 实现 一个 ftp CRT 不用 ftplib

  转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5590004.html   

  本来最初的想法是实现一个ftp服务器,用来实现用户的登陆注册和文件的断点上传下载等,结果做着做着就连CRT也顺带着跟着完成了,然后就变成了这样一个'不伦不类'的工具。用到的知识有hashlib加密密码传输,面向对象,sockeserver支持多客户访问,os.subprocess来处理系统自带的命令,然后自定义上传下载命令,以及如何实现断点续传,传输过程中的粘包问题,以及如何反射处理用户的输入。这里仅仅是为了娱乐,下面先来看一下效果图

      

        

一、客户端

首先定义以个客户端类,大致在类里面定义了这些方法,以后有需要的话,可以对其进行扩充,下面的类一初始化就会去执行start方法,如果在服务端注册登录成功的话,就会接下来执行internet方法,等待用户的输入,

class Client:
    def __init__(self, address):
        self.address = Client.get_ip_port(address)
        self.help_message = [
            '目前自定义的命令仅支持以下操作:\n'
            '\tput|filename',
            '\tget|filename',
        ]
        self.start()
        self.cwd = ''
 
    @staticmethod
    def get_ip_port(address):
        ip, port = address.split(':')
        return (ip, int(port))
 
    def register(self):
        try_counts = 0
        while try_counts < 3:
            user = input('请输入用户名:')
            if len(user) == 0:
                continue
            passwd = input('请输入用密码:')
            if len(passwd) == 0:
                continue
            pd = hashlib.sha256()
            pd.update(passwd.encode())
            self.socket.sendall('register|{}:{}'.format(user, pd.hexdigest()).encode())  # 发送加密后的账户信息
            ret = self.socket.recv(1024).decode()
            if ret == '202':
                print('注册成功请登录')
                os.mkdir(os.path.join(settings.USER_HOME_DIR, user))  # 在客户端也创建一个用户家目录
                os.mkdir(os.path.join(settings.USER_HOME_DIR, user, 'download_file'))
                os.mkdir(os.path.join(settings.USER_HOME_DIR, user, 'upload_file'))
                return True
            else:
                try_counts += 1
        sys.exit("Too many attemps")
 
    def login(self):
        try_counts = 0
        while try_counts < 3:
            user = input('请输入用户名:')
            self.user = user
            if len(user) == 0:
                continue
            passwd = input('请输入用密码:')
            if len(passwd) == 0:
                continue
            pd = hashlib.sha256()
            pd.update(passwd.encode())
            self.socket.sendall('login|{}:{}'.format(user, pd.hexdigest()).encode())  # 发送加密后的账户信息
            ret = self.socket.recv(1024).decode()
            if ret == '200':
                print('登陆成功!')
                self.cwd = self.socket.recv(1024).decode()
                return True
            else:
                print('用户或密码错误,请从新登陆:')
                try_counts += 1
        sys.exit("Too many attemps")
 
    def internet(self):
        pass<br>
    def process(self, cmd, argv):               # 处理自定义的命令
        pass<br>
    def help(self, argv=None):
        pass
 
    def put(self, argv=None):
        pass
 
    def get(self, argv=None):
        pass
 
    def start(self):
        self.socket = socket.socket()
        try:
            self.socket.connect(self.address)
        except Exception as e:
            sys.exit("Failed to connect server:%s" % e)
        print(self.socket.recv(1024).decode())
        inp = input('1、注册,2、登录,3、离开: ')
        if inp == '1':
            if self.register():
                if self.login():     # 登陆成功后进行交互操作
                    self.internet()
        elif inp == '2':
            if self.login():
                self.internet()
        else:
            sys.exit()
 
 
if __name__ == '__main__':
    # address = input('请输入FTP服务端地址(ip:port):')
    address = '127.0.0.1:9999'
    client = Client(address)

二、服务端  

  服务端是用socketserver来写的,以便出来多用户请求,每当用户来来请求的时候,先让其注册或登陆,注册完后,以用户的名字为其创建一个家目录,并将用户名和密码保存起来,将来用户登录的时候从db中取出数据和用户输入的密码进行对比,正确后让其进行下一步操作,用户密码输入三次以后,退出程序。服务端为了响应客户端的每一个操作,定义了一个函数专门接受客户端传来的每一次命令,然后对其分解,反射到具体的服务端具体的函数中去,这里需要先定义客户端传过来的数据的格式是 cmd|args。大家可以看到我上面客户端登陆认证的代码传输的数据格式 ('login|{}:{}'.format(user, pd.hexdigest())) ,这么做的道理就是为了服务端好统一进行处理。下面来一下代码具体怎么做的,

def handle(self):
        self.request.sendall('欢迎来到FTP服务器!'.encode())
        while True:
            data = self.request.recv(1
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇分析python程序运行时间的几种方法 下一篇文件扫描上传源码

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目