文件的上传
# 客户端
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()