python小练习七——支持多用户在线的FTP程序

题目要求

用户加密认证
允许同时多用户登录
每个用户有自己的家目录
允许用户在ftp server上随意切换目录
允许用户查看当前目录下文件
允许上传和下载文件,保证文件一致性

代码

server端
#!/usr/bin/env python3

import socketserver,os,pickle,hashlib

class MyServer(socketserver.BaseRequestHandler):


    def put(self, file_list):
        for file_name in file_list:
            file_name += "server"
            with open(file_name, 'w') as f:
                pass
            while True:
                flag = str(self.request.recv(1024), encoding = "utf8") #接收客户端开始的消息
                if flag == "start":
                    self.request.send(bytes("succ", encoding = "utf8")) #通知客户端成功
                else:
                    self.request.send(bytes("err", encoding = "utf8")) #通知客户端失败
                    break
                len_data = int(str(self.request.recv(1024), encoding = "utf8")) #接收长度
                self.request.send(bytes("长度接收成功", encoding = "utf8"))
                data = ''
                while len(data) < int(len_data):
                    a = str(self.request.recv(1245),encoding = "utf8") #拼接传输的数据
                    data += a
                print(data,end = '')
                with open(file_name, 'a') as f:
                    f.write(data)


    def get(self, file_list):
        for file_name in file_list:
            with open(file_name, "r") as f:
                for i in f:
                    self.request.sendall(bytes("start", encoding = "utf8"))
                    self.succ_info_1 = str(self.request.recv(1024), encoding = "utf8")
                    self.len_data = len(i)
                    print(self.len_data) #显示文件的长度
                    #服务端在发送数据的时候,不能直接发数字,不然接收端变量类型会不好处理,最好以字符串的形式再用encode编码,在这里用str(xxx, encoding = "utf8"会报错)
                    self.request.sendall(str(self.len_data).encode())
                    self.succ_info_2 = str(self.request.recv(1024), encoding = "utf8") #接收客户端确认接收的信息
                    print(self.succ_info_2)
                    self.request.send(bytes(i, encoding = "utf8")) #发送文件中的数据

                else:
                    self.request.sendall(bytes("end", encoding = "utf8")) #发送结束传输的信息
                    self.request.recv(1024)

    def cd(self, cd_dir):
        os.chdir(cd_dir[0])


    def pwd(self):
        print('start pwd')
        self.request.sendall(bytes(os.getcwd(), encoding = 'utf8')) 

    def ls(self):
        dir_list = os.popen('ls').read()
        #self.request.sendall(bytes(dir_list, encoding = 'utf8'))
        len_dir_list = len(dir_list)
        self.request.send(str(len_dir_list).encode())
        len_dir_list_succ = str(self.request.recv(1024), encoding = "utf8")
        self.request.send(bytes(dir_list, encoding = "utf8"))

    #def by(self):
    #   exit()

    def get_cmd(self):
        #存储各个功能的字典
        self.cmd_dict = {
                'get':self.get,
                'put':self.put,
                'cd':self.cd,
                'pwd':self.pwd,
                'ls':self.ls,
                #'by':self.by,
            }
        while True:
            self.get_cmd_data = str(self.request.recv(1024), encoding = "utf8") #接收命令
            print(self.get_cmd_data)
            self.cmd_list = self.get_cmd_data.split() #将指令与用户分开
            if len(self.cmd_list) > 1:
                self.cmd_dict[self.cmd_list[0]](self.cmd_list[1:]) #执行命令
            else:
                self.cmd_dict[self.cmd_list[0]]()

    def user_login(self):
        f = open('/home/dy/python_test/Day07/homework/user_passwd', 'rb')
        self.user_list = pickle.load(f)
        f.close()
        print(self.user_list)

        self.login_stat = False
        self.request.send(bytes("请输入用户名:", encoding = "utf8"))
        user_name = str(self.request.recv(1024), encoding = 'utf8')
        self.request.send(bytes("请输入密码:", encoding = "utf8"))
        user_password = self.request.recv(1024)
        text = hashlib.sha256()
        text.update(user_password)
        user_password = text.hexdigest()
        if self.user_list[user_name] == user_password:
            if not os.path.exists('/home/dy/python_test/Day07/homework/%s' % user_name):
                os.makedirs('/home/dy/python_test/Day07/homework/%s' % user_name)
            os.chdir('/home/dy/python_test/Day07/homework/%s' % user_name)
        self.login_stat = True


    def handle(self):
        print('server start ...')
        self.user_login()
        if self.login_stat:
            while True:
                self.get_cmd()



if __name__ == "__main__":
    ip,port = '127.0.0.1', 28888    
    server = socketserver.ThreadingTCPServer((ip, port), MyServer)
    server.serve_forever()
client端
#!/usr/bin/env python3

import socket,os,getpass

def get_file(file_list):
    for file_name in file_list:
        file_name += "client"
        with open(file_name, 'w') as f:
            pass
        while True:
            flag = str(client.recv(1024), encoding = "utf8") #接收服务端开始的消息
            if flag == "start":
                client.send(bytes("succ", encoding = "utf8")) #通知服务端成功
            else:
                client.send(bytes("err", encoding = "utf8")) #通知服务端失败
                break
            len_data = int(str(client.recv(1024), encoding = "utf8")) #接收长度
            client.send(bytes("长度接收成功", encoding = "utf8"))
            data = ''
            while len(data) < int(len_data):
                a = str(client.recv(1245),encoding = "utf8") #拼接传输的数据
                data += a
            print(data,end = '')
            with open(file_name, 'a') as f:
                f.write(data)


def put_file(file_list):
    for file_name in file_list:
        with open(file_name, "r") as f:
            for i in f:
                client.sendall(bytes("start", encoding = "utf8"))
                succ_info_1 = str(client.recv(1024), encoding = "utf8")
                len_data = len(i)
                print(len_data) #显示文件的长度
                #服务端在发送数据的时候,不能直接发数字,不然接收端变量类型会不好处理,最好以字符串的形式再用encode编码,在这里用str(xxx, encoding = "utf8"会报错)
                client.sendall(str(len_data).encode())
                succ_info_2 = str(client.recv(1024), encoding = "utf8") #接收客户端确认接收的信息
                print(succ_info_2)
                client.send(bytes(i, encoding = "utf8")) #发送文件中的数据

            else:
                client.sendall(bytes("end", encoding = "utf8")) #发送结束传输的信息
                client.recv(1024)

def pwd():
    server_dir = str(client.recv(2048), encoding = 'utf8')
    print(server_dir)


def ls():
    dir_list_len = int(str(client.recv(1024), encoding = "utf8"))
    client.send(bytes("长度接收成功", encoding = "utf8"))
    #print("dir_list:",len(dir_list))
    #print("dir_list_len",dir_list_len)
    dir_list = ''
    while len(dir_list) < dir_list_len:
        dir_list += str(client.recv(1024), encoding = "utf8")
    print(dir_list)

def by():
    exit()

def send_cmd():
    user_cmd_dict = {
            'get':get_file,
            'put':put_file,
            'pwd':pwd,
            'ls':ls,
            'by':by,
        }
    while True:
        user_input = input("请输入命令:")
        if user_input:break
    client.send(bytes(user_input, encoding = "utf8"))
    user_cmd_list = user_input.split()
    if (user_cmd_list[0] in ['put', 'get', ]) and (len(user_cmd_list) > 1) :
        user_cmd_dict[user_cmd_list[0]](user_cmd_list[1:])
    elif user_cmd_list[0] in ['pwd', 'ls', 'by'] :
        user_cmd_dict[user_cmd_list[0]]()



def user_login():
    title_name = str(client.recv(1024), encoding = "utf8")
    print(title_name)
    send_name = input()
    client.send(bytes(send_name, encoding = 'utf8'))
    title_passwd = str(client.recv(1024), encoding = 'utf8')
    print(title_passwd)
    send_passwd = getpass.getpass()
    client.send(bytes(send_passwd, encoding = 'utf8'))


if __name__ == '__main__':
    ip_port = ('127.0.0.1', 28888)

    client = socket.socket()
    client.connect(ip_port)
    user_login()
    while True:
        send_cmd()
添加用户脚本
#!/usr/bin/env python3

import hashlib, pickle
user_name = input("请输入用户名")
user_password = input("请输入密码")

text = hashlib.sha256()
text.update(bytes(user_password, encoding = "utf8"))
user_password = text.hexdigest()
with open("user_passwd", "rb") as f:
    user_list = pickle.load(f)
user_list[user_name] = user_password

with open("user_passwd", "wb") as f:
    pickle.dump(user_list, f)
用户文件初始化脚本
#!/usr/bin/env python3
import pickle
a = {}
with open("user_passwd", "wb") as f:
    pickle.dump(a, f)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值