收发收发文件与远程执行命令的程序原理是一摸一样的,比如下载文件的过程:
服务端
import socket
import os
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 50000))
server.listen(2)
count = 0
while True:
conn, client_addr = server.accept()
count += 1
print(f"[{count}] - got a new connection : {client_addr}")
while True:
cmd_byte = conn.recv(1024)
cmd = cmd_byte.decode()
if cmd.__eq__("exit"):
print(f"{client_addr} close the connection")
break
print(f"from client {client_addr} : {cmd}")
# 执行指令
# 1.服务端收到 客户端指令,解析,判断get开头,代表下载文件
if cmd.startswith("get"):
# 2.提取文件名,判断文件是否在服务器上存在,如果存在就下载
file_name = cmd.split()[1]
file_path = os.path.join("F:\\Animation\\", file_name)
if os.path.isfile(file_path):
file_size = os.path.getsize(file_path)
# 3.拿到文件的大小,生成消息头,发给客户端
msg_head = f"|{file_size}".zfill(16).encode()
conn.send(msg_head)
# 4.打开文件,发送文件内容
file = open(file_path, "rb")
for line in file:
conn.send(line)
file.close()
print(f"file {file_name} has sent to client, size {file_size}")
else:
conn.send("|0".zfill(16).encode())
server.close()
客户端
import socket
import uuid
import os
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 50000))
while True:
file_name = input("download>>>").strip()
if file_name.__eq__("exit"):
break
client.send(file_name.encode())
# 获取文件的大小
file_size = int(client.recv(32).decode().split("|")[1])
if file_size == 0:
print("获取文件格式不对:get 文件名")
continue
suffix = file_name.split(".")[1]
file_name_download = os.path.join("F:\\Animation\\", str(uuid.uuid1())+"."+suffix)
file = open(f"{file_name_download}", "ab")
# 循环获取数据
receive_size = 0
while receive_size < file_size:
file_info = client.recv(1024)
# 更新获取的数据
receive_size += len(file_info)
file.write(file_info)
print(file_size, file_info)
file.close()
print(f"file download done...size{file_size}")
client.close()
测试
进度条使用
客户端修改
客户端相关代码
import socket
import uuid
import os
# 封装的进度条
def process_bar(total_size):
old_receive_percent = 0
new_receive_percent = 0
while new_receive_percent <= 100:
receive_size = yield
new_receive_percent = int((receive_size / total_size) * 100)
# 只有有增长时才增加进度条
if new_receive_percent > old_receive_percent:
print(f"\r{new_receive_percent * '>'}{new_receive_percent}%", end="")
old_receive_percent = new_receive_percent
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 50000))
while True:
file_name = input("download>>>").strip()
if file_name.__eq__("exit"):
break
client.send(file_name.encode())
# 获取文件的大小
file_size = int(client.recv(32).decode().split("|")[1])
if file_size == 0:
print("获取文件格式不对:get 文件名")
continue
suffix = file_name.split(".")[1]
file_name_download = os.path.join("F:\\Animation\\", str(uuid.uuid1()) + "." + suffix)
file = open(f"{file_name_download}", "ab")
# 循环获取数据
receive_size = 0
# 使用进度条
file_process_bar = process_bar(file_size)
file_process_bar.__next__()
while receive_size < file_size:
file_info = client.recv(1024)
# 更新获取的数据
receive_size += len(file_info)
file.write(file_info)
# 更新进度条
file_process_bar.send(receive_size)
file.close()
print(f"file download done...size{file_size}")
client.close()