网络编程学习(6)—— 基于SOCKET实现文件传输功能
文件传输功能和执行终端命令功能的区别
文件传输功能实现和实现执行终端命令功能的区别
- 不需要执行命令,即不需要使用
subprocess 模块 - 判断文件大小方式不是文件内容的长度,而是使用
os 模块
import os
os.path.getsize(文件路径)
- 上传文件时,为防止一次上传完整文件导致内存不足,上传时,一行行上传
with open(文件, "rb") as f:
for line in f:
conn.send(line)
代码实现
服务端
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()
客户端
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()
运行结果
|