示例#1
0
    def login(self, sock, wdata):
        while True:
            try:
                login_info = set_struct.recv_message(sock)
                if login_info == None:
                    break
            except BlockingIOError:
                continue
            #z在客户端登录时如果失去连接,那么会导致服务端也会被终止,在此捕获异常
            except ConnectionResetError:
                queue.get()
                break
            #验证帐号是否正确,将返回的结果True和False返回给客户端,客户端以此凭据来展示登录成功或失败
            is_success, username = login_obj.verify_account(login_info)
            wdata[sock] = [
                username,
            ]
            is_success_dict = {'is_success': is_success, 'username': username}
            set_struct.send_message(sock, is_success_dict)

            if is_success_dict['is_success'] == True:
                print(self.put_response_code['204'])
                return
            else:
                print(self.put_response_code['205'])
                continue
示例#2
0
    def check_put_pause(self, put_file_dict, puted_file, pause_init, sock):
        #检查文件的MD5码
        #1、如果文件MD5码一致,则会调用put_file_existed方法告知客户端
        #2、如果MD5码不一致,且断点续传配置文件中也存在上传文件的断点记录的话,会让用户选择是否继续断点续传
        puted_file_md5 = set_md5.set_file_md5(puted_file)

        if puted_file_md5 == put_file_dict['file_md5']:
            f, recv_size = self.put_file_existed(sock)
            return f, recv_size
        else:
            if os.path.exists(pause_init):
                recv_size = conf_obj.set_conf({'file_name': puted_file},
                                              'read_recv_size', pause_init)

                put_status_dict = {
                    'put_status': False,
                    'put_message': self.put_response_code['202'],
                    'put_again': 'yes',
                    'is_choice': 'yes'
                }
                set_struct.send_message(sock, put_status_dict)
                diff_dict = set_struct.recv_message(sock)

                if diff_dict['is_pause_go'] == 'y':
                    f = set_file.write_file(puted_file, 'ab')

                if diff_dict['is_pause_go'] == 'n':
                    f = set_file.write_file(puted_file, 'wb')
                    recv_size = 0

                return f, int(recv_size)
示例#3
0
    def put_diff(self, put_file, file_size, put_file_dict):
        '''接收服务端针对下载文件的状态反馈
        1、如果反馈信息为True则可以开始执行puting方法,开始上传文件
        2、如果反馈信息为False,是因为由服务端检查了,准备上传文件在断点续传配置文件中的记录
        3、由用户选择是否进行断点续传,提供了y和n选项
        '''
        while True:
            put_status_dict = set_struct.recv_message(self.client)
            while True:
                print(put_status_dict['put_message'])
                if put_status_dict['is_choice'] == 'yes':
                    is_pause_go = input('>>>').lower()

                if put_status_dict['put_status'] == False:
                    if put_status_dict['put_again'] == 'yes':
                        if is_pause_go in ['n' 'y']:
                            diff_dict = {'is_pause_go': is_pause_go}
                            set_struct.send_message(self.client, diff_dict)
                            break
                        else:
                            print(self.put_request_code['205'])
                            continue
                    else:
                        return
                else:
                    self.puting(put_file, put_status_dict, file_size,
                                put_file_dict)
                    return
示例#4
0
    def get(self, cmd, filename):
        '''初始下载文件函数方法,在函数中验证准备下载的文件是否存在
        1、如果文件存在,且MD5码一致,则告知用户无需重复下载
        2、如果文件存在,但MD5码不一致,则调用check_get_pause方法,检查断点续传配置文件
        3、如果文件不存在,则会调用downloading方法执行下载方法
        '''
        pause_init = os.path.join(self.base_dir, 'db', 'pause.init')
        get_file = os.path.join(self.base_dir, 'download', self.username,
                                filename)

        if not os.path.exists(get_file):
            set_struct.send_message(self.client, {'cmd': cmd})
            # self.client.send(cmd.encode(self.encoding))
            get_dict = set_struct.recv_message(self.client)
            if get_dict['get_status'] == False:
                print(self.put_request_code['201'])
                return

            confirm_dict = {'confirm_get': True}
            set_struct.send_message(self.client, confirm_dict)
            print(self.put_request_code['200'])
            set_bar.set_bar()
            f = set_file.write_file(get_file, 'wb')
            recv_size = 0
            self.downloading(f, recv_size, get_file, get_dict)
        else:
            set_struct.send_message(self.client, {'cmd': cmd})
            # self.client.send(cmd.encode(self.encoding))
            get_dict = set_struct.recv_message(self.client)
            if get_dict['get_status'] == False:
                print(self.put_request_code['201'])
                return

            get_file_md5 = set_md5.set_file_md5(get_file)
            if get_file_md5 == get_dict['file_md5']:
                self.get_file_existed()
                return
            else:
                f, file_name, recv_size = self.check_get_pause(
                    get_file, pause_init)
                confirm_dict = {
                    'confirm_get': True,
                    'is_pause_go': self.is_pause_go
                }
                set_struct.send_message(self.client, confirm_dict)
                self.downloading(f, int(recv_size), file_name, get_dict)
示例#5
0
    def ll(self, cmd):
        #通过ll函数方法,可以查看用户通过cd命令到达指定目录后的文件
        set_struct.send_message(self.client, {'cmd': cmd})

        file_list = set_struct.recv_message(self.client)
        #如果返回的文件列表为空,则告知用户,否则打印文件
        if len(file_list) == 0:
            print(self.put_request_code['210'])
            return
        else:
            print('文件列表如下:')
            for file in file_list:
                print(file)
示例#6
0
    def cd(self, cmd, directory):
        print(directory)
        '''通过cd命令,用户可以切换目录'''
        root_directory = os.path.join(self.base_dir, 'share')
        root_directory_list = os.listdir(root_directory)
        #如果用户指定切换的目录,在云盘列表,或使用cd / | cd ..命令时会将请求发送至客户端
        if directory in root_directory_list or directory in ['/', '..']:
            set_struct.send_message(self.client, {'cmd': cmd})

            self.current_directory = os.path.split(
                set_struct.recv_message(self.client))[1]
            if self.current_directory == 'share':
                self.current_directory = '/'
        else:
            print('没有找到%s' % directory)
示例#7
0
    def view(self, cmd, username):
        #用户可通过view命令浏览个人云盘空间文件的方法
        if username != self.username:
            print(self.put_request_code['208'])
            return

        set_struct.send_message(self.client, {'cmd': cmd})
        view_info = set_struct.recv_message(self.client)
        #如果返回的结果是列表,则告知用户云盘是空的
        #如果返回的结果是字典,则会调用show_view_file犯法打印文件
        if isinstance(view_info, list):
            print(self.put_request_code['209'])

        if isinstance(view_info, dict):
            self.show_view_file(view_info)
示例#8
0
    def put(self, filename, sock, wdata, rlist):
        print('jin')
        #服务端接收到put命令,处理上传文件的函数犯法
        #1、如果文件存在,则会调用check_put_pause方法,检查断点续传配置文件爱你
        #2、如果文件不存在,且磁盘空间满足上传文件的大小,则会调用puting方法执行上传
        put_file_dict = set_struct.recv_message(sock)
        print('put_file_dict', put_file_dict)
        puted_file = os.path.join(self.base_dir, 'share', wdata[sock][0],
                                  filename)
        pause_init = os.path.join(self.base_dir, 'db', 'pause.init')
        free_size = self.free_size(sock, wdata)

        if os.path.exists(puted_file):
            f, recv_size = self.check_put_pause(put_file_dict, puted_file,
                                                pause_init, sock)
            if f == None:
                return
        else:
            f = None
            recv_size = 0

        if put_file_dict['file_size'] < free_size:
            put_status_dict = {
                'put_status': True,
                'put_message': self.put_response_code['200'],
                'put_again': 'no',
                'is_choice': 'no',
                'recv_size': recv_size
            }
            set_struct.send_message(sock, put_status_dict)

            t = Thread(target=self.puting,
                       args=(f, recv_size, put_file_dict, puted_file, sock,
                             rlist))
            t.start()
            t.join()
        else:
            self.size_not_enough(put_file_dict, sock, wdata)
示例#9
0
    def login(self, client):
        while True:
            login_choice = input('还没有账号?按r注册账号,已有账号请按g>>>:')
            if login_choice in ['r', 'R', 'g', 'G']:
                if login_choice in ['r', 'R']:
                    self.register()
                    continue

                if login_choice in ['g', 'G']:
                    if not os.path.exists(
                            '%s/%s/%s' %
                        (self.base_dir, 'db', 'account.init')):
                        print('当前系统内还没有任何账号,请先注册')
                        continue

                    while True:
                        username = input('请输入用户名:')
                        password = input('请输入密码:')

                        login_info = {
                            'username': username,
                            'password': password
                        }

                        set_struct.send_message(client, login_info)
                        is_success_dict = set_struct.recv_message(client)

                        if is_success_dict['is_success'] == True:
                            self.username = is_success_dict['username']
                            print('连接成功')
                            return username
                        else:
                            print('用户名或密码错误,请重新输入')
                            continue
            else:
                print('您的输入有误,请重新输入')
                continue
示例#10
0
    def run(self):
        link_status_file = os.path.join(self.base_dir, 'db', 'link_status.txt')
        self.server_bind()
        conn_is_login = []
        conn_not_login = []
        rlist = [
            self.server,
        ]
        wlist = []
        wdata = {}
        while True:
            rl, wl, xl = select.select(rlist, wlist, [], 0.5)
            for sock in rl:
                if sock == self.server:
                    conn, caddr = self.server.accept()
                    #如果有客户端连接,如果队列没有满,则放入caddr,放入后如果队列满,则会创建文件,该文件的存在与否表示队列是否满载
                    if conn:
                        if not queue.full():
                            queue.put(caddr)
                            if queue.full():
                                set_file.write_file(link_status_file, 'w')
                        if queue.empty():
                            os.remove(link_status_file)
                    rlist.append(conn)
                    conn_not_login.append(conn)
                else:
                    if sock in conn_not_login:
                        t = Thread(target=self.login, args=(sock, wdata))
                        t.start()
                        t.join()
                        conn_is_login.append(sock)
                        conn_not_login.remove(sock)
                        break
                    while True:
                        try:
                            cmd_dict = set_struct.recv_message(sock)
                            cmd = cmd_dict['cmd']
                            if not cmd:
                                queue.get()
                                os.remove(link_status_file)
                                print(self.put_response_code['203'])
                                sock.close()
                                rlist.remove(sock)
                                wdata.pop(sock)
                                break
                            wlist.append(sock)
                            wdata[sock].append(cmd)
                            break
                        except BlockingIOError:
                            break
                        except Exception:
                            queue.get()
                            #通过文件是否存在控制并发量,如果客户端断开则删除该文件,表示允许客户端连接
                            if os.path.exists(link_status_file):
                                os.remove(link_status_file)
                            print(self.put_response_code['203'])
                            sock.close()
                            #在客户端登录时,还没有获取到rlist和wdata的值,所以当客户端重新连接时,服务端会报错
                            try:
                                rlist.remove(sock)
                                wdata.pop(sock)
                            except KeyError:
                                break
                            break

            for sock in wl:
                request_method = wdata[sock][1].split()[0]

                if hasattr(self, request_method):
                    #不同长度的命令分别处理,需要该判断,因为调用函数时传递的参数不同
                    if len(wdata[sock][1].split()) == 2:
                        request_content = wdata[sock][1].split()[1]
                        func = getattr(self, request_method)
                        #从之前的通过反射判断如果方法存在,那么就执行func()变为发起一个线程去执行这个方法
                        t = Thread(target=func,
                                   args=(request_content, sock, wdata, rlist))
                        t.start()
                        rlist.remove(sock)
                        wlist.remove(sock)
                        #之前没加这一句,下载的都是同一个文件
                        del wdata[sock][1]
                    else:
                        func = getattr(self, request_method)
                        t = Thread(target=func, args=(sock, wdata, rlist))
                        t.start()
                        rlist.remove(sock)
                        wlist.remove(sock)
                        del wdata[sock][1]
示例#11
0
    def pwd(self, cmd):
        #查看当前所在目录的命令
        set_struct.send_message(self.client, {'cmd': cmd})

        current_directory = set_struct.recv_message(self.client)
        print(current_directory)