python-实现tcp上传下载文件

1320阅读 0评论2021-08-17 专注的阿熊
分类:Python/Ruby

import socket

import struct

import json

import os

sc= socket.socket()

sc.connect(('127.0.0.1',9997))

''' 验证用户名密码的函数,验证区 '''

def send_user(user,pwd):#发送用户的账户和密码

    user_len = len(user.encode('utf-8'))

    leng = struct.pack('i',user_len)

    sc.send(leng)#用户的字节码长度

    sc.send(user.encode('utf-8'))#发送用户名的字节码

    pwd_len = len(pwd.encode('utf-8'))

    leng = struct.pack('i', pwd_len)

    sc.send(leng)#密码的字节码长度

    sc.send(pwd.encode('utf-8'))#密码的字节码

''' 接收服务端的功能的函数,功能区 '''

#上传文件的路径

#上传文件的路径

path = r'F:\installsotf\python file\python全栈\day30\作业\test_up'

#下载文件的保存位置

load_path=r'F:\installsotf\python file\python全栈\day30\作业\download_file'

#接收服务端提供的功能列表,功能循环中第一个调用

def recv_function_list(sc):

    leng = sc.recv(4)

    leng = struct.unpack('i', leng)[0]

    cont = sc.recv(leng).decode('utf-8')

    return cont

#将要发送的文件名和大小写到字典中,下面三个函数,实现文件的上传

def get_file(path):

    file=os.path.basename(path)

    size=os.path.getsize(path)

    dic = {'file':file,'size':size}

    return dic

def up_file(path,size):

    with open(path, 'rb')as fp:

        while size > 0:

            msg = fp.read(1024)

            sc.send(msg)

            size -= len(msg)

def upto_file(path):

    # path=input('输入文件的绝对路径:').strip()

    if os.path.exists(path):

        dic = get_file(path)  # 获取字典【如果将path改成输入,就可以随意上传文件了】

        size = dic['size']

        dic_byte = json.dumps(dic).encode('utf-8')  # 先转成json,再转成bytes

        dic_leng = len(dic_byte)  # 获取bytes的长度

        leng = struct.pack('i', dic_leng)

        sc.send(leng)  # 发送字典dic的长度

        sc.send(dic_byte)  # 发送字典的内容

        # 打开要操作的文件,用rb模式

        up_file(path, size)  # 调用上传文件

        return True

    else:

        return False

#下面这个函数实现文件的下载:

def down_file(path):#将文件下载到哪个位

    # 收到用户的选择。

    # print(58)

    leng = sc.recv(4)  # 接收文件名和大小组成的字典

    # print(60,len(leng))

    leng = struct.unpack('i', leng)[0]

    dic = sc.recv(leng).decode('utf-8')

    dic = json.loads(dic)  # 获取到{file:file,'size':size}

    # print(dic)

    # print(65)

    path = os.path.join(path, dic['file'])

    size = dic['size']

    with open(path, 'wb')as fp:

        while size > 0:

            cont = sc.recv(1024)

            fp.write(cont)

            size -= len(cont)

while 1:

    print('1、登录\n2、注册')

    chioce = input('输入的选择(q/Q退出):').strip()

    chioce_list=['登录','注册']

    if chioce=='1' or chioce=='2':

        user = input('输入用户名:').strip()

        pwd = input('输入密码:').strip()

        sc.send(chioce.encode('utf-8'))#发送选择给服务端

        send_user(user,pwd)

        ret = sc.recv(3).decode('utf-8')#yes 或者 not

        if ret =='yes':

            print(f'{chioce_list[int(chioce)-1]}成功。')

            '''  接收服务端提供功能的代码 :功能区'''

            if chioce=='1':#代表用户是在登录,且登录成功了,那么就可以享受服务端提供的上传下载文件功能。

                while 1:

                    cont = recv_function_list(sc)

                    print(cont)

                    choice = input('输入你的选择(e/E退出):').strip()

                    if choice.isdecimal():

                        sc.send(choice.encode('utf-8'))  # 告诉服务器要进行的操作

                        choice = int(choice)

                        if choice == 1:  # 上传文件

                            while 1:

                                path = input('输入文件绝对路径:')

                                path = path.replace('\\', '/')

                                ret = upto_file(path)

                                if ret:

                                    print('上传成功')

                                num = input('回车继续上传,stop退出上传:').strip()

                                if num=='goto' or 'stop':

                                    sc.send(num.encode('utf-8'))

                                    if num == 'stop':

                                        break

                                else:

                                    sc.send('none'.encode('utf-8'))

                        elif choice == 2:

                            # 1、接收文件列表的长度和内容

                            len_list = sc.recv(4)  # 接收列表的长度字节码

                            leng = struct.unpack('i', len_list)[0]  # unpacke成数字

                            leng = int(leng)

                            file_list = sc.recv(leng).decode('utf-8')

                            file_list = json.loads(file_list)

                            while 1:

                                print('-*' * 20)

                                print()

                                for i, name in enumerate(file_list, 1):

                                    print(f'{i},{name}')

                                num = input('输入你选择:').strip()

                                if num.isdecimal():

                                    num = int(num)

                                    if num > 0 and num <= len(file_list):

                                        # 2、发送文件序号的长度和内容

                                        leng = len(str(num).encode('utf-8'))

                                        leng = struct.pack('i', leng)

                                        sc.send(leng)  # 将文件序号的字节长度发送过去

                                        sc.send(str(num).encode('utf-8'))  # 将文件序号发送过去。

                                        # print('调用down_file')#走到这里了

                                        # 3、接收文件的内容

                                        down_file(load_path)

                                        print('下载文件成功。')

                                        # print('调用down_file')

                                        yes_not = input('回车继续下载,输入 stop 退出:').strip()

                                        if yes_not=='stop' or yes_not=='goto':

                                            sc.send(yes_not.encode('utf-8'))

                                            if yes_not == 'stop':

                                                break

                                        else:

                                            sc.send("none".encode('utf-8'))

                                    else:

                                        print('无此选择。')

                                        sc.send('0'.encode('utf-8'))

                                else:

                                    print('输入有误。')

                        else:

                            print('无此选择。')

                    elif choice.upper() == 'E':

                        sc.send('E'.encode('utf-8'))

                        break

                    else:

                        print('输入有误。')

                    '''接收服务端提供功能的代码的尾部:功能区'''

        else:

            print(f'{chioce_list[int(chioce)-1]}失败。')

    elif chioce.upper()=='Q':

        #发送Q给服务端,说明要退出。

        sc.send('Q'.encode('utf-8'))

        print('退出系统。')

        break

    else:

        print('输入有误。')

sc.close()

上一篇:Python 深度学习6:PyTorch 卷积神经网络
下一篇:遥感影像语义分割——数据增强(图像和原图同时增强)