Python开发Day8(socket练习)

客户端代码:

#!/usr/bin/python3.5
__auth__ = 'WuYongQi'
import socket,pickle,os,sys

def up_duandian(obj,filename):
    duandian = str(obj.recv(1024),encoding='utf-8')
    if duandian == 'No':
        print('文件不存在!')
    else:
        duandian = int(duandian)
        print(duandian)
        obj.sendall(bytes(str(os.stat(filename).st_size),encoding='utf-8'))
        f = open(filename,'rb')
        f.seek(duandian)
        j = ''
        biaoshi = duandian/os.stat(filename).st_size*100
        for i in f:
            duandian += len(i)
            if biaoshi <= duandian/os.stat(filename).st_size*100:
                biaoshi += 1
                j = j+''
            sys.stdout.write(str(float(duandian/os.stat(filename).st_size*100))+'%\t |'+j+"\r")
            sys.stdout.flush()
            obj.sendall(i)
        return '发送完成'

def down_duandian(obj,filename):
    if str(obj.recv(1024),encoding='utf-8') == 'No':
        print('服务器端文件不存在!')
    else:
        f1 = open(filename,'rb')
        f1.read()
        weizhi = str(f1.tell())
        f1.close()
        print(weizhi)
        obj.sendall(bytes(weizhi,encoding='utf-8'))
        weizhi = int(weizhi)
        file_size = int(obj.recv(1024))
        f = open(filename,'r+b')
        j = ''
        biaoshi = weizhi/file_size*100
        while True:
            if file_size == weizhi:
                break
            data = obj.recv(1024)
            f.write(data)
            weizhi += len(data)
            if biaoshi <= weizhi/file_size*100:
                biaoshi += 1
                j = j+''
            sys.stdout.write(str(float(weizhi/file_size*100))+'%\t |'+j+"\r")
            sys.stdout.flush()
        return '接收完成!'

def user_ftp(obj):
    print(str(obj.recv(1024),encoding='utf-8'))
    user_in_ftp = input('>>>')
    if user_in_ftp == 'q':
        obj.sendall(bytes(user_in_ftp,encoding='utf-8'))
        return False
    obj.sendall(bytes(user_in_ftp,encoding='utf-8'))
    if user_in_ftp == '1':
        file_name = input('请输入上传后文件名称:')
        server = str(obj.recv(1024),encoding='utf-8')
        obj.sendall(bytes(file_name,encoding='utf-8'))
        if server == 'uploading':
            return ftp_server(obj)
    server = str(obj.recv(1024),encoding='utf-8')
    if server == 'downloading':
        return ftp_client(obj)

def ftp_server(obj):
    user_up_ftp = input('请输入要上传的文件路径\n>>>')
    file_size = os.stat(user_up_ftp).st_size#查看文件大小
    file_finish = 0 #文件已上传大小已完成
    obj.sendall(bytes(str(file_size),encoding='utf-8'))#要上传的文件大小传给服务端
    obj.recv(1024)#接收一次服务端的信息,以防止粘包
    f = open(user_up_ftp,'rb')
    j = ''
    biaoshi = 1
    for i in f:
        file_finish += len(i)
        if biaoshi <= file_finish/file_size*100:
            biaoshi += 1
            j = j+''
        sys.stdout.write(str(float(file_finish/file_size*100))+'%\t |'+j+"\r")
        sys.stdout.flush()
        obj.sendall(i)
    return '发送完成'


def ftp_client(obj):
    ser_name = input('请输入服务器上的文件名:')
    obj.sendall(bytes(ser_name,encoding='utf-8'))
    filename = input('请输入下载后的名称:')
    file_size = str(obj.recv(1024),encoding='utf-8')#要上传文件的大小
    if file_size == 'No':
        return '文件不存在!'
    file_size = int(str(obj.recv(1024),encoding='utf-8'))
    obj.sendall(bytes('OK',encoding='utf-8'))#给客户端发一个消息,防止粘包
    f = open(filename,'wb')
    file_finish = 0
    j = ''
    biaoshi = 1
    while True:
        try:
            if file_size == file_finish:
                break
            data = obj.recv(1024)
            file_finish += len(data)
            if biaoshi <= file_finish/file_size*100:
                biaoshi += 1
                j = j+''
            sys.stdout.write(str(float(file_finish/file_size*100))+'%\t |'+j+"\r")
            sys.stdout.flush()
            f.write(data)
        except KeyboardInterrupt:
            print('客户端强制退出!')
            break
    return '接收完成!'


obj = socket.socket()
obj.connect(('127.0.0.1',8080))
data1 = pickle.loads(obj.recv(1024))
for i,k in enumerate(data1,1):
    print(i,k)
while True:
    biaoshi = 0
    data12 = str(obj.recv(1024),encoding='utf-8')
    if data12 == 'ftp':
        obj.sendall(bytes('OK',encoding='utf-8'))
        user_in = user_ftp(obj)
        if user_in:
            print(str(obj.recv(1024),encoding='utf-8'))
            continue
        else:
            obj.sendall(bytes('q',encoding='utf-8'))
            break
    elif data12 == 'command':
        usr_command = input('请输入要执行的命令 >>>>')
        obj.sendall(bytes(usr_command,encoding='utf-8'))
        comm_size = str(obj.recv(1024),encoding='utf-8')
        print(comm_size)
        obj.sendall(bytes('OK',encoding='utf-8'))
        if comm_size.isdigit():
            comm_size = int(comm_size)
            text = ''
            for i in range(1,comm_size):
                try:
                    data = obj.recv(1024)
                    print(str(data,encoding='utf-8'))
                    text = '%s%s'%(text,str(data,encoding='utf-8'))
                except Exception:
                    print('强制退出!')
                    break
            # while True:
            #     try:
            #         if comm_size <= 0:
            #             print(comm_size,1111111111111111111)
            #             break
            #         print(comm_size,'9999999999999')
            #         data = obj.recv(1024)
            #         text = '%s%s'%(text,data)
            #         print(str(data,encoding='utf-8'))
            #         comm_size -= len(bytes(data))
            #     except KeyboardInterrupt:
            #         print('强制退出!')
            #         break
            print(str(text),'123123123123123123123123123123123123123123')
            print(str(obj.recv(1024), encoding='utf-8'))
            obj.sendall(bytes('OK',encoding='utf-8'))
            continue
        else:
            command_result = pickle.loads(obj.recv(1024))
            print(str(command_result, encoding='utf-8'))
            print(str(obj.recv(1024), encoding='utf-8'))
        continue
    elif data12 == 'duandian':
        user_xuanze = input('请输入断点续传操作:\n'
                            '1、上传文件\n'
                            '2、下载文件')
        obj.sendall(bytes(user_xuanze,encoding='utf-8'))
        obj.recv(1024)
        if user_xuanze == '1':
            file_up = input('请输入上传文件名:')
            file_up2 = input('请输入上传的本地文件路径:')
            obj.sendall(bytes(file_up,encoding='utf-8'))
            up_duandian(obj,file_up2)
            continue
        elif user_xuanze == '2':
            file_down = input('请输入下载的服务器端的文件名:')
            file_down2 = input('请输入下载的本地文件路径:')
            obj.sendall(bytes(file_down,encoding='utf-8'))
            down_duandian(obj,file_down2)
            continue
        else:
            print('输入错误!')
            continue
    else:
        inp = input(data12)
        if inp.isdigit():
            if int(inp) >= len(data1) or int(inp) >= 1:
                obj.sendall(bytes(str(int(inp)-1), encoding='utf-8'))
            else:
                print('输入的值有误,请从新输入')
        elif biaoshi == 0:
            if inp == 'q':
                obj.sendall(bytes(inp,encoding='utf-8'))
                break
            else:
                biaoshi += 1
                obj.sendall(bytes(inp,encoding='utf-8'))
        else:
            obj.sendall(bytes(inp,encoding='utf-8'))
View Code

服务端格式:

  • sock_server:
    • bin:
      • server.py
        #!/usr/bin/python3.5
        __auth__ = 'WuYongQi'
        import socket,socketserver,pickle,os,sys
        sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)),'config'))
        import class_user,hashlib,sys_config
        username = ''
        def login(conn):
            hash = hashlib.sha512()
            conn.sendall(bytes('请输入用户名', encoding='utf-8'))
            global username
            username = str(conn.recv(1024), encoding='utf-8')
            conn.sendall(bytes('请输入密码', encoding='utf-8'))
            hash.update(conn.recv(1024))
            urpd = class_user.user(username, hash.hexdigest()).login()
            if urpd:
                conn.sendall(bytes('登陆成功!(按回车继续)', encoding='utf-8'))
            else:
                conn.sendall(bytes('账号密码有误!(按回车继续)', encoding='utf-8'))
                login(conn)
        
        def register(conn):
            hash = hashlib.sha512()
            conn.sendall(bytes('请输入用户名', encoding='utf-8'))
            username = str(conn.recv(1024), encoding='utf-8')
            urdp = class_user.user(username).register()
            if not urdp:
                conn.sendall(bytes('用户名重复,请重新输入!(按回车继续)',encoding='utf-8'))
                register(conn)
            while True:
                conn.sendall(bytes('请输入密码', encoding='utf-8'))
                pwd1 = conn.recv(1024)
                conn.sendall(bytes('请确认密码', encoding='utf-8'))
                pwd2 = conn.recv(1024)
                if pwd1== pwd2:
                    hash.update(pwd2)
                    urpd = class_user.user(username, hash.hexdigest()).register()
                    if urdp:
                        conn.sendall(bytes('注册成功!(按回车继续)', encoding='utf-8'))
                        break
                    else:
                        conn.sendall(bytes('注册失败!(按回车继续)', encoding='utf-8'))
                        register(conn)
                else:
                    conn.sendall(bytes('密码确认失败!(按回车继续)',encoding='utf-8'))
                    continue
        
        def command(conn):
            import subprocess
            conn.sendall(bytes('command',encoding='utf-8'))
            command = str(conn.recv(1024),encoding='utf-8')
            try:
                a = subprocess.check_output(command,shell=True)
            except Exception:
                return '命令有误!(按回车继续)'
            if len(a) >= 1024 :
                file_size = len(a)  # 查看大小
                print(file_size,'kjghjdgj')
                conn.sendall(bytes(str(file_size), encoding='utf-8'))  # 要上传的文件大小传给服务端
                conn.recv(1024)  # 接收一次客户端的信息,以防止粘包
                print(str(a,encoding='gbk'))
                for i in str(a,encoding='utf-8'):
                    conn.sendall(bytes(str(i),encoding='utf-8'))
                return '发送完成'
            else:
                conn.sendall(pickle.dumps(a))
            return '执行完毕'
        
        def duandianxuchuan(conn):
            conn.sendall(bytes('duandian',encoding='utf-8'))
            xuanze = str(conn.recv(1024),encoding='utf-8')
            if xuanze == '1':
                conn.sendall(bytes('文件名',encoding='utf-8'))
                filename = str(conn.recv(1024),encoding='utf-8')
                return up_file(conn,filename)
            elif xuanze == '2':
                conn.sendall(bytes('文件名',encoding='utf-8'))
                filename = str(conn.recv(1024),encoding='utf-8')
                return down_file(conn,filename)
        
        def up_file(conn,filename):
            if os.path.exists(os.path.join(sys_config.USER_DB,'home',username,filename)):
                f1 = open(os.path.join(sys_config.USER_DB,'home',username,filename),'r+b')
                f1.read()
                weizhi = f1.tell()
                conn.sendall(bytes(str(weizhi),encoding='utf-8'))
                print(weizhi)
                file_size = int(str(conn.recv(1024),encoding='utf-8')) - weizhi
                print(file_size)
                while True:
                    try:
                        print(file_size)
                        if file_size == 0:
                            break
                        data = conn.recv(1024)
                        f1.write(data)
                        file_size -= len(data)
                    except KeyboardInterrupt:
                        print('客户端强制退出!')
                        break
                f1.close()
                print('完成')
                return '接收完成!(按回车继续)'
            else:
                print('文件不存在!(按回车继续)')
                return 'No'
        
        def down_file(conn,filename):
            if not os.path.exists(os.path.join(sys_config.USER_DB,'home',username,filename)):
                print('文件不存在!(按回车继续)')
                return 'No'
            else:
                conn.sendall(bytes('kong',encoding='utf-8'))
                duandian = int(conn.recv(1024))
                print(type(duandian))
                print(os.stat(os.path.join(sys_config.USER_DB,'home',username,filename)).st_size)
                conn.sendall(bytes(str(os.stat(os.path.join(sys_config.USER_DB,'home',username,filename)).st_size),encoding='utf-8'))
                f = open(os.path.join(sys_config.USER_DB,'home',username,filename),'r+b')
                f.seek(duandian)
                for i in f:
                    conn.sendall(i)
                f.close()
                return '发送完成!(按回车继续)'
        def ftpserver(conn):
            conn.sendall(bytes('ftp',encoding='utf-8'))
            conn.recv(1024)
            conn.sendall(bytes('1、上传文件\n2、下载文件\nq、退出系统', encoding='utf-8'))
            user_ftp =  str(conn.recv(1024),encoding='utf-8')
            if user_ftp == '1':
                conn.sendall(bytes('uploading',encoding='utf-8'))#请输入上传后的文件名称:
                file_name = str(conn.recv(1024),encoding='utf-8')
                return uploading(conn,file_name)
            elif user_ftp == '2':
                conn.sendall(bytes('downloading',encoding='utf-8'))#请输入要下载的文件名称:
                file_name = str(conn.recv(1024),encoding='utf-8')
                return downloading(conn,file_name)
            elif user_ftp == 'q':
                return None
        
        def uploading(conn,filename):
            print(os.path.join(sys_config.USER_DB,'home',username,filename))
            file_size = int(str(conn.recv(1024),encoding='utf-8'))#要上传文件的大小
            conn.sendall(bytes('OK',encoding='utf-8'))#给客户端发一个消息,防止粘包
            f = open(os.path.join(sys_config.USER_DB,'home',username,filename),'wb')
            while True:
                try:
                    if file_size == 0:
                        break
                    data = conn.recv(1024)
                    f.write(data)
                    file_size -= len(data)
                except KeyboardInterrupt:
                    print('客户端强制退出!')
                    break
            return '接收完成!'
        
        def downloading(conn,filename):
            user_up_ftp = filename
            print(user_up_ftp)
            if os.path.exists(os.path.join(sys_config.USER_DB,'home',username,user_up_ftp)):
                file_size = os.stat(user_up_ftp).st_size#查看文件大小
                conn.sendall(bytes(str(file_size),encoding='utf-8'))#要上传的文件大小传给服务端
                conn.recv(1024)#接收一次客户端的信息,以防止粘包
                f = open(user_up_ftp,'rb')
                for i in f:
                    conn.sendall(i)
                return '发送完成'
            else:
                return 'No'
        
        
        class server_much(socketserver.BaseRequestHandler):
            def handle(self):
                print('asdkvjhalskjbvjkasbldvrawe')
                conn = self.request
                print('客户端ip:',self.client_address[0],'\n客户端端口:',self.client_address[1])
                index = ['登陆', '注册']
                conn.sendall(pickle.dumps(index))
                conn.sendall(bytes('请输入接下来的操作,按Q退出!',encoding='utf-8'))
                # while True:
                data1 = conn.recv(1024)
                if str(data1,encoding='utf-8') == 'q':
                    conn.close()
                    # break
                if data1.strip().isdigit():
                    if index[int(data1)] == '登陆':
                        login(conn)
                        while True:
                            user_inp = '1、ftp\n2、command\n3、断点续传\n任意字符串退出系统\n>>>>>'
                            conn.sendall(bytes(user_inp,encoding='utf-8'))
                            user_in = str(conn.recv(1024),encoding='utf-8')
                            if user_in.isdigit():
                                if user_in == '0':
                                    ret = ftpserver(conn)
                                    conn.sendall(bytes(ret,encoding='utf-8'))
                                    conn.sendall(bytes(user_inp,encoding='utf-8'))
                                    continue
                                elif user_in == '1':
                                    ret = command(conn)
                                    conn.sendall(bytes(ret,encoding='utf-8'))
                                    continue
                                elif user_in == '2':
                                    ret = duandianxuchuan(conn)
                                    conn.sendall(bytes(ret,encoding='utf-8'))
                                    continue
                            else:
                                conn.close()
                                break
                    elif index[int(data1)] == '注册':
                        register(conn)
        if __name__ == '__main__':
            server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),server_much)
            server.serve_forever()
        View Code
    • config:
      • class_user.py
        #!/usr/bin/python3.5
        __auth__ = 'WuYongQi'
        import pickle,hashlib,os,sys
        CONFIG = os.path.join(os.path.dirname(os.path.dirname(__file__)),'config')
        USER_DB = os.path.join(os.path.dirname(os.path.dirname(__file__)),'user_db')
        
        class user:
        
            def __init__(self,username,password=0):
                self.username = username
                self.password = password
        
            def login(self):
                a = open(USER_DB+'/db','r', encoding='utf-8')  # 获取数据
                for i in a:  # 循环获取数据的每一行
                    i = i.strip()  # 去掉两边的空格或其他字符串
                    i = i.split('#')  # 以#号分割
                    if self.username == i[0] and self.password == i[1]:  # 判断用户输入的账号密码是用索引去对应的位置是否一样
                        print('登陆成功')  # 返回值
                        return True
                return False  # 返回值
        
            def register(self):
                with open(USER_DB+'/db', 'r+', encoding='utf-8') as f:  # 去读现在又的账号密码
                    for i in f:  # 循环获取数据的每一行
                        i = i.strip()  # 去掉两边的空格或其他字符串
                        i = i.split('#')  # 以#号分割
                        if self.username == i[0]:  # 判断用户输入的账号是否存在
                            return False  # 存在输出并重新执行
                        if self.password == 0:
                            return 'N'
                    f.write('\n' + self.username + '#' + self.password)  # 成功创建用户,并一#号分割账号密码
                    return '注册成功'  # 返回注册成功
        View Code
      • sys_config.py
        #!/usr/bin/python
        # -*- coding: utf-8 -*-
        __author__ = 'WuYongQi'
        import os
        CONFIG = os.path.join(os.path.dirname(os.path.dirname(__file__)),'config')
        USER_DB = os.path.join(os.path.dirname(os.path.dirname(__file__)),'user_db')
        View Code
    • user_db:
      • home
        • wuqi
          • 存放用户文件
        • db#用户登录账号密码:
          wu#933ec0a594667c5f77870cfccfd7a1d66e2b7cd74e685b1bbfbd07a07690e6d421c835ea0522c1308d95866c7b728996083b678350900dfa8c5c4393462c5d5d
          admin#e54a9de41b39d03910cd04cd713612b10906a45d54cc158f042711629ef15e0e07eaa71958c8f1404a899bed3036a462f650116b28265822948a2cf25783b20b
          alex#e7205add494f33c5ebe8bda3a41c2c1a3e1152733ce7988d7de7190b076976d718a4e8bd3b5dc3211c810a57ca89a68eff74d55ab9b3ea7f3b5488f53e177888
          wuqi#e0de6b065348b12c68f663b7b965fa3e87101409668a7a9948e28ebefc1ab87ea21800012a49ae4d9cca94ac2ec94fa0e075978deaf8f9c2c4763a645e294f78
          View Code

           

posted @ 2016-06-19 02:47  WuYongQi。  阅读(223)  评论(0编辑  收藏  举报