文件的上传

文件的上传

# 客户端
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:\pythonlearning\video2', 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()
posted @ 2019-08-19 23:41  竣~  阅读(135)  评论(0编辑  收藏  举报