实现文件传输功能
在通信循环中实现文件传输功能,以下载图片1.png为例,命令为:get 1.png
1、客户端发送命令:
cmd = input(">>:").strip() # get 1.png
if not cmd:continue
phone.send(cmd.encode("utf-8"))
2、服务端收命令:
res = conn.recv(8096)
if not res:break
3、服务端解析命令:
cmds = res.decode("utf-8").split() #得到['get','1.png']
filename = cmds[1]
4、服务端以读的方式打开文件,读取文件内容发送给客户端:
- 第一步:制作固定长度数据头
header_dic = {
"filename": filename,
"md5": "xxxdxxx",
'file_size': os.path.getsize(r"%s\%s"%(share_dir,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"%(share_dir,filename)),"rb") as f:
# conn.send(f.read())
for line in f:
conn.send(line) # 逐行读取再发送,有效节约系统内存,但是会粘包
5、 客户端以写的方式打开一个新的文件,接收服务端发来的文件的内容写入客户的新文件:
- 第一步:先收数据头的长度
obj = phone.recv(4) header_size = struct.unpack('i',obj)[0]
- 第二步:再收数据头
header_bytes = phone.recv(header_size)
- 第三步:从数据头中解析出对真实数据的描述信息
header_json = header_bytes.decode("utf-8")
header_dic = json.loads(header_json)
print(header_dic)
# 查询数据头中包含的信息
total_size = header_dic["file_size"]
filename = header_dic["filename"]
- 第四步:接收真实的数据
with open("%s\%s"%(download_dir,filename),"wb") as f:
recv_size = 0
while recv_size < total_size:
line= phone.recv(1024)
# 接收到一行就写入一行
f.write(line)
recv_size += len(line)
print("总大小:%s 已经下载大小:%s"%(total_size,recv_size))
程序目录结构
完整代码演示
1、服务端代码
import socket
import subprocess
import struct
import json
import os
share_dir = r"E:\mydesktop\My_Code\后端\b站网络编程\05文件传输\server\share"
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(("127.0.0.1",9910))
phone.listen(5)
print("starting...")
while True:
conn,client_addr = phone.accept()
print(client_addr)
while True:
# 1、收命令
res = conn.recv(8096)
if not res:break
# 2、解析命令,提取相应命令参数
cmds = res.decode("utf-8").split() #得到['get','a.txt']
filename = cmds[1]
# 3、以读的方式打开文件,读取文件内容发送给客户端
# 第一步:制作固定长度的报头。
header_dic = {
"filename": filename,
"md5": "xxxdxxx",
'file_size': os.path.getsize(r"%s\%s"%(share_dir,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"%(share_dir,filename)),"rb") as f:
# conn.send(f.read())
for line in f:
conn.send(line) # 逐行读取再发送,有效节约系统内存,但是会粘包
conn.close()
phone.close()
2、客户端代码
import socket
import struct
import json
download_dir = r"E:\mydesktop\My_Code\后端\b站网络编程\05文件传输\client\Download"
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(("127.0.0.1",9910))
while True:
# 1、发命令
cmd = input(">>:").strip() # get a.txt
if not cmd:continue
phone.send(cmd.encode("utf-8"))
# 2、以写的方式打开一个新的文件,接收服务端发来的文件的内容写入客户的新文件
# 第一步:先收报头的长度
obj = phone.recv(4)
header_size = struct.unpack('i',obj)[0]
# 第二步:再收报头
header_bytes = phone.recv(header_size)
# 第三步:从数据头中解析出对真实数据的描述信息
header_json = header_bytes.decode("utf-8")
header_dic = json.loads(header_json)
print(header_dic)
# 查询数据头中包含的信息
total_size = header_dic["file_size"]
filename = header_dic["filename"]
# 第四步:接收真实的数据
with open("%s\%s"%(download_dir,filename),"wb") as f:
recv_size = 0
while recv_size < total_size:
line= phone.recv(1024)
# 接收到一行就写入一行
f.write(line)
recv_size += len(line)
print("总大小:%s 已经下载大小:%s"%(total_size,recv_size))
phone.close()
3、先运行服务端,再运行客户端,在客户端控制台输入命令:get 1.png
1.png将被下载到Download目录下。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122896.html