基于python的文件传输
生活中我们如何通过脚本进行传输文件呢,以下提供如何进行传输txt,jpg等格式的文件
代码如下:
客户端.py
import socket
import time
import threading
import struct #将int类型打包成byte类型
import json #反序列化
path=r''
def run():
cmd=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建一个套接字对象,tcp格式,面向网络
cmd.connect(('127.0.0.1',8081)) #连接测试地址,并且设置端口号
while True:
try:
#1.发命令
cmd1=input("请输入文件名称").strip() #【get,a.txt】
if not cmd1: continue #如果没有命令直接继续执行
cmd.send(cmd1.encode('utf-8')) #将发送的命令通过操作系统并且通过utf-8编码
#2.拿命令的结果,并且打印
#第一步,先拿到数据的长度
header=cmd.recv(4) #接收一下报头的长度
header_size=struct.unpack('i',header)[0] #将报头的byte类型解压成int类型
header_bytes=cmd.recv(header_size) #接收数据部分
header_json=header_bytes.decode('utf-8'); #将数据的byte类型经过解码utf-8
header_dic=json.loads(header_json) #通过json的包进行反序列化成字符串类型
print(header_dic) #打印一下字符串
total_size=header_dic['file_size'] #取出字符串中总长度
filename=header_dic["filename"] #取出输入的姓名
#第二步,从报头解析出,从filename的报头进行解析
num=0
with open('%s\%s'%(path,filename),'wb') as file:
recv_size = 0 #设置接受的字符长度
while recv_size < total_size: #经过循环遍历出总长度
data = cmd.recv(1024) #接收1024个字节的长度
file.write(data) #写出文件数据
recv_size+=len(data)
num+=1
print("正在下载: {},总共大小 {},下载进度为{:.2%}".format(recv_size, total_size,(recv_size/total_size))+"{"+"|"*(num)+"}")
print("it is be download successfully")
except:
print("指定文件不存在")
cmd.close()
if __name__ == '__main__':
print("i am parents process, my ID is"+threading.current_thread().name)
print("waiting for connecting")
path=input(r'请输入要下载的路径')
threading1=threading.Thread(target=run)
threading1.start()
print("i am child process, My ID is "+threading1.name)
time.sleep(10)
服务器端.py
import socket
import subprocess
import json
import os
import struct
import threading
path=r'D:\pythonProject\testfile\文件传输\share\share' #注意修改服务器端的文件夹
def run():
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建套接字对象设置tcp格式并且事面向网络的类型
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# print(phone)
#2.绑定手机卡
phone.bind(('127.0.0.1',8081))
#3.开机
phone.listen(5)
#4.等电话连接
print('starting....')
while True:
conn,client_addr=phone.accept() #等待客户端主机被接听的过程
print(client_addr)
#收发消息
while True:#通讯循环
try:
#1.收命令
res=conn.recv(8096) #[get,filename]
if not res: break
cmd=res.decode('utf-8').split()
filename=cmd[1]
#2.执行命令
# obj = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# stdout=obj.stdout.read()
# stderr=obj.stderr.read()
#3.把命令的结果返回给客户端
#第一步制作固定长度的报头
header_dic={
'filename':filename,
'md5':'xxxdxx',
'file_size':os.path.getsize(r'%s\%s'%(path,filename)),
}
header_json=json.dumps(header_dic)
header_bytes=header_json.encode('utf-8')
#发送报头的长度
conn.send(struct.pack('i', len(header_bytes)))
#第一步,把报头(固定长度)发送给客户
conn.send(header_bytes)
#发送最真实的数据
with open('%s\%s'%(path,filename),'rb') as file:
for line in file:
conn.send(line)
except:
print("指定文件不存在")
break
#挂电话
conn.close()
phone.close()
if __name__ == '__main__':
run()
结果截图: