• 【1011 | Day 42】socket实现ftp文件的上传和下载


    1. server端代码

    import socket
    import json
    import struct
    import os
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    soc.bind(('127.0.0.1', 8021))
    
    soc.listen(5)
    # 上传函数
    def uploading_file():
        while True:
            try:
                ftp_dir = r'F:shpython11pycharmworkfirst_projectstudy_startday32ftp_dir'
                if not os.path.isdir(ftp_dir):  # 这个是作为我们上传了之后的文件放在这个位置,你改成自己本地的
                    os.mkdir(ftp_dir)
                head_bytes_len = conn.recv(4)  # 拿到struct后的头长度
    
                head_len = struct.unpack('i', head_bytes_len)[0]  # 取出真正的头长度
    
                # 拿到真正的头部内容
                head_bytes = conn.recv(head_len)
                # 反序列化后取出头
                head = json.loads(head_bytes)
    
                file_name = head['file_name']
                file_path = os.path.join(ftp_dir,file_name)
                data_len = head['data_len']
                with open(file_path, 'wb') as fw:
                    while data_len > 1024:
                        fw.write(conn.recv(1024))
                        data_len -= 1024
                    else:
                        fw.write(conn.recv(data_len))
                conn.send(f'上传文件 {file_name} 成功'.encode('utf8'))
            except Exception:
                break
    
    
    
    while True:
        print('等待客户端连接。。。')
        conn, addr = soc.accept()
        print('客户端已连接:', addr)
        choice = conn.recv(1).decode('utf8')
        if choice == 'q':
            break
        if choice == '1':
            print('客户端选择了ftp上传服务')
            uploading_file()
        elif choice == '2':
            print('客户端选择了ftp下载服务')
            while True:
                try:
                    ftp_dir = r'F:shpython11pycharmworkfirst_projectstudy_startday32ftp_dir'
                    if not os.path.isdir(ftp_dir):  # 这个是作为我们上传了之后的文件放在这个位置,你改成自己本地的
                        os.mkdir(ftp_dir)
                    file_list = os.listdir(ftp_dir)
                    head = {'file_list': file_list}
                    head_bytes = json.dumps(head).encode('utf8')
                    head_bytes_len = struct.pack('i', len(head_bytes))
    
                    conn.send(head_bytes_len)
                    conn.send(head_bytes)
    
                    client_head_bytes_len = conn.recv(4)
    
                    client_head_len = struct.unpack('i', client_head_bytes_len)[0]
                    client_head_bytes = conn.recv(client_head_len)
                    client_head = json.loads(client_head_bytes)
                    choice = client_head['choice']
                    file_name = file_list[int(choice)]
    
                    file_path = os.path.join(ftp_dir, file_name)
    
                    with open(file_path, 'rb') as fr:
                        data = fr.read()
    
                    server_head = {'data_len': len(data), 'file_name': file_name}  # 自定义头
                    server_head_bytes = json.dumps(server_head).encode('utf8')
                    server_head_bytes_len = struct.pack('i', len(server_head_bytes))
    
                    conn.send(server_head_bytes_len)
                    conn.send(server_head_bytes)
                    conn.send(data)
                    conn.send(f'下载文件 {file_name} 成功'.encode('utf8'))
    
                except Exception:
                    break
    
        conn.close()
    soc.clone()
    

    2. client端代码

    import socket
    import os
    import struct
    import json
    client_soc = socket.socket()
    
    client_soc.connect(('127.0.0.1',8021))
    
    # 获取文件夹下的文件
    def get_file_list(file_path):
        if os.path.exists(file_path):
            if os.path.isfile(file_path):
                return True,file_path
            else:
                file_list = os.listdir(file_path)
                if file_list==[]:
                    return False,'当前文件夹为空,请重新选择'
                else:
                    return True,file_list
        else:
            return False,'你输入的文件路径不对'
    
    # 上传函数
    def uploading_file():
        print('欢迎进入ftp文件上传系统')
        while True:
            dir_path = input('请输入文件所在的文件夹路径或文件路径(输入q退出):')
    
            if dir_path == 'q':
                print('你选择了退出上传系统')
                break
            flag, dir_list = get_file_list(dir_path)
            if flag:
                if os.path.isfile(dir_path):
                    file_name = dir_path.split('\')[-1]
                    file_path = dir_path
                else:
                    for ind, file in enumerate(dir_list):
                        print(f'文件编号:{ind} 对应的文件名为:{file}')
                    choice = input('请输入文件编号进行上传:').strip()
                    choice = int(choice)
                    file_name = dir_list[choice]
                    file_path = os.path.join(dir_path, file_name)
    
                with open(file_path,'rb') as fr:
                    data = fr.read()
                head = { 'data_len': len(data),'file_name':file_name}  # 自定义头
                head_bytes = json.dumps(head).encode('utf8')
                head_bytes_len = struct.pack('i',len(head_bytes))
    
                client_soc.send(head_bytes_len)
                client_soc.send(head_bytes)
                client_soc.send(data)
                msg = client_soc.recv(1024)
                print(msg.decode('utf8'))
            else:
                print('你输入的文件路径不存在')
    
    # 下载函数
    def download():
        print('欢迎来到ftp下载系统')
        head_bytes_len = client_soc.recv(4)
        head_len = struct.unpack('i', head_bytes_len)[0]
        head_bytes = client_soc.recv(head_len)
        head = json.loads(head_bytes)
        file_list = head['file_list']
        if file_list == []:
            print('当前ftp中无文件可下载,等待上传中')
        else:
            print('当前ftp中有如下文件')
            for ind,file in enumerate(file_list):
                print(f'文件编号:{ind} 对应的文件名为:{file}')
            choice = input('请选择要下载文件的编号:')
            choice_head = {'choice':choice}  # 自定义头
    
            choice_head_bytes = json.dumps(choice_head).encode('utf8')
    
            choice_head_bytes_len = struct.pack('i', len(choice_head_bytes))
            client_soc.send(choice_head_bytes_len)
            client_soc.send(choice_head_bytes)
    
            # 接收用户传递过来的文件
            client_head_bytes_len = client_soc.recv(4)  # 拿到struct后的头长度
    
            client_head_len = struct.unpack('i', client_head_bytes_len)[0]  # 取出真正的头长度
            # 拿到真正的头部内容
            client_head_bytes = client_soc.recv(client_head_len)
            # 反序列化后取出头
            client_head = json.loads(client_head_bytes)
            file_name = client_head['file_name']
            data_len = client_head['data_len']
    
            with open(file_name, 'wb') as fw:
                while data_len > 1024:
                    fw.write(client_soc.recv(1024))
                    data_len -= 1024
                else:
                    fw.write(client_soc.recv(data_len))
            msg = client_soc.recv(1024)
            print(msg.decode('utf8'))
    
    
    while True:
        msg = '''
        1.文件上传
        2.文件下载
        q.退出系统
        '''
        print(msg)
        choice = input('请做出你的选择:').strip()
        client_soc.send(choice.encode('utf8'))
        if choice == 'q':
            print('你选择了退出系统')
            break
        if choice == '1':
            uploading_file()
    
        elif choice == '2':
            download()
    
  • 相关阅读:
    layUI--实现分页
    maven项目-----Dynamic Web Module 3.0 requires Java 1.6 or newer
    js---open打开新窗口
    hibernate常见问题?
    eclipse如何修改dynamic web module version
    设计模式之五种创建型模式学习笔记
    设计模式学习笔记
    数据定义语言(DDL Data Definition Language)基础学习笔记
    idea安装成功后,设置字体、快捷键、配置jdk等操作
    基于Redis实现分布式锁
  • 原文地址:https://www.cnblogs.com/fxyadela/p/11656963.html
Copyright © 2020-2023  润新知