TCP服务端
"""
编写cs架构的软件,实现客户端可以下载服务端的文件,如图片、视频、文本等
"""
import socketserver
import os
import json
import struct
def base_path(*paths):
return os.path.normpath(os.path.join(__file__, '..', 'db', *paths))
class MyRequestHandler(socketserver.BaseRequestHandler):
DB_PATH = base_path()
def header(self, request=False, warn=None, info=None, file_name=None, file_size=None):
# 定制头部
dic = {
'request': request,
'file_name': file_name,
'file_size': file_size,
'warn': warn,
'info': info,
}
dic_json_bytes = json.dumps(dic).encode('utf-8')
header_bytes = struct.pack('i', len(dic_json_bytes))
self.request.send(header_bytes)
self.request.send(dic_json_bytes)
def verify_path(self, path_json):
# 逻辑判断
current_path = base_path(*path_json.split('/'))
print('current_path:', current_path)
if not os.path.isfile(current_path):
return
if len(self.DB_PATH) >= len(current_path):
return
return current_path
def send(self, current_path):
file_size = os.path.getsize(current_path)
file_name = os.path.basename(current_path)
info = '执行命令成功! 正在为您下载文件....'
self.header(True, file_size=file_size, file_name=file_name, info=info)
with open(current_path, 'rb') as f:
for line in f:
# 发送数据
self.request.send(line)
def handle(self):
print('客户端访问:', self.client_address)
while True:
try:
path_json = self.request.recv(1024).decode('utf-8')
print('path_json:', path_json)
if not path_json:
break
# 1. 定制头部
# 2. 逻辑判断
current_path = self.verify_path(path_json)
if not current_path:
self.header(warn='对不起, 您的文件路径不存在!')
continue
# 3. 发送数据
self.send(current_path)
except ConnectionResetError:
break
except Exception:
break
print("客户端断开连接:", self.client_address)
self.request.close()
s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyRequestHandler)
s.serve_forever()
TCP客户端
"""
编写cs架构的软件,实现客户端可以下载服务端的文件,如图片、视频、文本等
"""
import os
import json
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(("127.0.0.1", 8080))
def progress(percent, symbol='#', width=50):
if percent > 1:
percent = 1
show_progress = ("[%%-%ds]" % width) % (int(percent * width) * symbol)
print("\r%s %.2f%%" % (show_progress, percent * 100), end='')
while True:
cmd = input("[下载: get /路径/路径../文件]请输入命令>>: ").strip()
if not cmd:
continue
cmd_list = cmd.split()
if len(cmd_list) != 2:
print('对不起, 输入错误!')
continue
cmd, path = cmd_list
if cmd != 'get':
print("对不起, 下载文件请执行命令get")
continue
# 1. 发送命令
client.send(path.encode('utf-8'))
# 2. 解包
import struct
header_bytes = client.recv(4)
json_dic_bytes_length = struct.unpack('i', header_bytes)[0]
json_dic_bytes = client.recv(json_dic_bytes_length)
dic = json.loads(json_dic_bytes.decode('utf-8'))
print(dic)
# 3. 逻辑判断
request = dic['request']
if not request: # 失败
print(dic['warn'])
continue
info, file_size, file_name = dic['info'], dic['file_size'], dic['file_name']
# 接收数据
print(info)
print("start recv........")
with open(file_name, 'wb') as f:
recv_size = 0
while recv_size < file_size:
data_bytes = client.recv(1024)
f.write(data_bytes)
recv_size += len(data_bytes)
percent = recv_size / file_size
progress(percent)
print("\nend recv........")
client.close()