• 文件的上传


    文件的上传

    # 客户端
    import socket
    import os
    import json
    import struct
    
    # 创建一个socket对象,不写参数,默认使用TCP协议
    client = socket.socket()
    # 客户端连接服务端(ip+port)
    client.connect(('127.0.0.1', 8080))  # '127.0.0.1是本机回还地址'
    # 客户端连接成功后即开始通信循环
    while True:
        # 给出视频所在文件夹路径
        dir_path = r'G:培训视频day28视频'
        # 拿到文件夹下的视频列表
        file_list = os.listdir(dir_path)
        # 循环打印视频列表
        for index, file_name in enumerate(file_list, 1):
            print(index, file_name)
        # 用户选择一个视频
        choice = input('>>>:').strip()
        # 对输入进行判断,拿到合法输入
        if not choice:
            print('输入不能为空!')
            continue
        if not choice.isdigit():
            print('请输入数字!')
            continue
        # 至此输入为纯数字字符串,将其转化成数字
        choice = int(choice) - 1  # 循环打印时从1开始,此时需要减1
        # 判断输入是否在范围
        if choice not in range(len(file_list)):
            print('输入不在范围!')
            continue
        # 至此拿到用户想上传的视频file_list[choice]
        file_to_upload_name = file_list[choice]
        # 拼接文件路径
        file_path = os.path.join(dir_path, file_to_upload_name)
        # 拿到文件大小
        file_size = os.path.getsize(file_path)
        # 构造字典
        d = {'file_size': file_size, 'file_to_upload_name': file_to_upload_name}
        # 将字典序列化,序列化后的结果是字符串
        json_d = json.dumps(d)
        # 制作字典报头,生成的结果是bytes类型,长度由模式决定,第二个参数必须为整数
        header = struct.pack('i', len(json_d.encode('utf-8')))
        # 发送字典报头
        client.send(header)
        # 发送序列化后的字典,由于发送的数据必须为bytes类型,所以要将序列化后的字典编码
        client.send(json_d.encode('utf-8'))
        # 现在开始发送数据,以rb模式打开,读出的数据就可以直接发送
        with open(file_path, 'rb') as f:
            # 打印信息
            print('开始传输!')
            # 循环取出数据并发送
            for line in f:
                client.send(line)
            # 打印信息
            print('传输完成!')
    
    
    # 服务端
    import socket
    import json
    import struct
    import os
    
    # 创建一个socket对象,没有参数默认为TCP协议
    server = socket.socket()
    # 服务端绑定ip+port
    server.bind(('127.0.0.1', 8080))
    # 设置半连接池
    server.listen(5)
    
    # 开始连接循环
    while True:
        conn, addr = server.accept()
        # 开始通信循环
        while True:
            # 异常处理
            try:
                # 接收报头
                header = conn.recv(4)
                # 解析报头,还原序列化后字典的长度,第二个参数是bytes类型
                json_d_length = struct.unpack('i', header)[0]
                # 接收序列化后的字典
                json_d = conn.recv(json_d_length)
                # 反序列化得到真实字典,由于传过来的数据时bytes类型,所以要解码
                d = json.loads(json_d.decode('utf-8'))
                # 取出文件大小和文件名字
                file_size = d.get('file_size')
                file_name = d.get('file_to_upload_name')
                # 拼接文件路径
                file_path = os.path.join(r'G:pythonlearningvideo2', file_name)
                # 打开文件,接收数据并写入,以wb模式打开,方便写入
                with open(file_path, 'wb') as f:
                    # 打印信息
                    print('开始传输!')
                    # 循环接收数据
                    real_size = 0
                    while real_size < file_size:
                        data = conn.recv(1024)
                        f.write(data)
                        real_size += len(data)
                    # 打印信息
                    print('传输结束!')
            except ConnectionResetError as e:  # e接收报错信息
                print(e)  # 打印报错信息
                break
        conn.close()
    
  • 相关阅读:
    Ubuntu 20.04 国内下载eclipse 网速慢解决方案
    Ubuntu20.04+GeForce RTX 2080 SUPER+cuda11.1+cudnn8.0.4+openCV4.4.0编译
    计算机专业考研复试面试----计算机组成原理
    计算机专业考研复试面试----操作系统
    Gabor滤波(个人学习)
    局部保留投影算法(个人学习)
    【转载】matlab常用函数
    latex常见的错误(自己经常出现的)
    latex常用的宏包(转载)
    C语言基础知识
  • 原文地址:https://www.cnblogs.com/DcentMan/p/11380554.html
Copyright © 2020-2023  润新知