TCP下载器(客户端带进度显示功能,可实现大文件传输)
server.py服务端需先运行
import socket
import os
# 定义接受客户端信息并处理文件的函数
def exec_file(client_socket,client_addr):
print("等待client的指令")
# 接收client要下载的文件名
file_name = client_socket.recv(1024).decode()
# 获取文件的字节大小
file_size = os.path.getsize(file_name)
print("%s 的大小为:%s Byte"%(file_name,file_size))
#将文件大小这个信息发送给客户端,使其能够循环接收数据(它是为了给客户端终止循环的条件)
client_socket.send(str(file_size).encode())
print("client:%s--下载的文件名为:%s"%(str(client_addr),file_name))
# 服务器在当前目录搜索,是否有这个文件,并打开读取内容
file_data = None
print("正在读取当前文件内容.....")
try:
f = open(file_name,"rb")
file_data = f.read()
# print(len(file_data))
except:
print("%s 不存在"%file_name)
finally:
f.close()
# 发送文件内容给客户端
client_socket.send(file_data)
print("文件传输完成!")
# 定义服务端
def sever():
# 创建服务器socket对象
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定本地的服务器IP和端口
server_socket.bind(("127.0.0.1",8888))
# 将服务器socket变被动模式,有客户端主动发起连接建立
server_socket.listen(5)
# 循环,实现服务器等待多个客户端建立连接
while True:
print("等待客户端建立连接.....")
# 等待客户端建立连接
client_socket,client_addr = server_socket.accept()
# 调用上面处理文件的函数,实现客户端下载文件任务
exec_file(client_socket,client_addr)
# 关闭当前客户端服务socket
client_socket.close()
print("断开当前客户端连接")
print("-"*20)
# 关闭服务器socket
server_socket.close()
if __name__ == "__main__":
sever()
import socket
import sys
import time
# 进度条展示下载进度
def processBar(num,total):
rate = num / total
rate_num = int(rate * 100)
if rate_num == 100: # \r 回到当前行的行首,本行之前的内容会被覆盖 ,使进度条集中在一行显示
r = '\r[%s>]%d%%\n'%('=' * int(rate_num / 3),rate_num,)
else:
r = '\r[%s>]%d%%' % ('=' * int(rate_num / 3), rate_num,)
sys.stdout.write(r)# 打印进度,本质就是print
sys.stdout.flush# 强制刷新标准输出
# 定义客户端下载功能函数
def client_download():
# 创建client套接字对象
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 创建与服务器的连接
client_socket.connect(("127.0.0.1",8888))
# 将要下载的文件名发送给服务器
file_name = input("请输入要下载的文件名:")
# 将字符串编码为字节码发送给服务器
client_socket.send(file_name.encode())
# 接收服务器发送的文件大小
file_size = int(client_socket.recv(512).decode())
# 记录接收的数据长度(也可理解为大小)
recv_len = 0
print("下载进度:")
with open("[new]-" + file_name, "ab") as f:
while True: # 此循环由于每次只接收1024字节大小的文件内容,所以循环写入文件内容
recv_data = client_socket.recv(1024)
f.write(recv_data)
# 累加记录接收的数据大小
recv_len += len(recv_data)
# 循环调用进度条函数,展示接收进度
processBar(recv_len,file_size)
# 如果接收的数据大小累计到,等于文件大小时,跳出循环,完成下载
if recv_len == file_size:
print("下载完成")
break
# 关闭客户端socket
client_socket.close()
# import os
if __name__ == "__main__":
start_time = time.time()
client_download()
end_time = time.time()
print("本次下载耗时:%f秒"%(end_time-start_time))
# print(os.path.getsize())
效果展示:
服务终端显示:
客户端显示: