文件传输功能和执行终端命令功能的区别
文件传输功能实现和实现执行终端命令功能的区别
- 不需要执行命令,即不需要使用
subprocess
模块 - 判断文件大小方式不是文件内容的长度,而是使用
os
模块
import os
os.path.getsize(文件路径)
- 上传文件时,为防止一次上传完整文件导致内存不足,上传时,一行行上传
with open(文件, "rb") as f:
for line in f:
conn.send(line)
代码实现
服务端
# coding=gbk
import os.path
import socket
import struct
import json
dir_path = "C:\\Users\\ASUS\\Desktop\\CSDN\\网络编程\\09-文件传输功能\\server\\share\\"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 8080))
server.listen(5)
while True: # 链接循环
conn,addr = server.accept()
print(addr)
while True: # 通信循环
try:
cmd = conn.recv(8096)
if not cmd:
break
# 获取要下载的文件名
filename = cmd.split()[1].decode("utf-8")
# 获取文件大小,即字节长度
total_size = os.path.getsize("%s%s" % (dir_path, filename))
# 报头字典
header_dic = {
"filename": filename,
"total_size": total_size
}
# 字典转换为字符串
header_bytes = json.dumps(header_dic)
# 字符串长度编码并发送
header_bytes_length = struct.pack("i", len(header_bytes))
# 发送报头编码
conn.send(header_bytes_length)
# 发送字典字符串
conn.send(header_bytes.encode("utf-8"))
# 发送文件
with open("%s%s" % (dir_path, filename), "rb") as f:
for line in f:
conn.send(line)
except ConnectionResetError:
break
conn.close()
server.close()
客户端
# coding=gbk
import socket
import json
import struct
dir_path = "C:\\Users\\ASUS\\Desktop\\CSDN\\网络编程\\09-文件传输功能\\client\\download\\"
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8080))
while True:# 通信循环
cmd = input(">>: ").strip()
if not cmd:
continue
client.send(cmd.encode("utf-8"))
filename = cmd.split()[1]
# 接收报头并解码
header_bytes_length = struct.unpack("i", client.recv(4))[0]
# 接收字典字符串
header_bytes_size = 0
header_bytes = b""
while header_bytes_size < header_bytes_length:
data = client.recv(1024)
header_bytes += data
header_bytes_size += len(data)
# 字典字符串转换成字典
header_dic = json.loads(header_bytes)
print(header_dic)
# 下载文件
total_size = header_dic["total_size"]
file_size = 0
with open("%s%s" % (dir_path, filename), "wb") as f:
while file_size < total_size:
data = client.recv(1024)
f.write(data)
file_size += len(data)
print("下载完成")
client.close()