利用socket模块实现文件下载功能

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()



client优化版.py

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())

效果展示:
服务终端显示:
在这里插入图片描述
客户端显示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孜孜孜孜不倦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值