博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用生成器制作一个简单的客户端接收文件的进度条
阅读量:5320 次
发布时间:2019-06-14

本文共 5526 字,大约阅读时间需要 18 分钟。

  一、首先看一个生成器的例子:

def run():    count = 0    while 1:        n = yield count        print(n,'---',count)        count += 1g = run()#一开始调用__next__方法不会唤醒,只有用send方法才能打印g.__next__()##send的用法g.send('whw')g.send('whw1')g.send('whw2')g.send('whw3')g.send('whw4')

  这里,我们在第一次使用__next__()方法是是不会唤醒生成器的,后面加上send()方法可以打印出相应的结果:

  二、在客户端利用生成器加进度条的简单思路:

  大致的过程为:我们先定义一个当前文件传输时传输的数据占文件总大小的比例current_percent变量,注意这个current_percent是不断叠加的:当进行第二次传输时变成了第一次传输的百分比与第二次传输的百分比的和...以此类推;另外,我们把每一次接收的“current_percent”的“当前值”赋值给另外一个变量last_percent,只要current_percent大于last_percent,表明文件就没有存完,只有当二者相等的时候才表示文件全部传完——也就是说,我们的迭代条件就是current_percent >last_percent

  生成器函数的代码如下:

def progress_bar(total_size, current_percent=0, last_percent=0):    '''进度条功能'''    while 1:        received_size = yield current_percent        current_percent = int(received_size / total_size * 100)        if current_percent > last_percent:            print("*" * int(current_percent / 2) + "{percent}%".format(percent=current_percent), end='\r',                  flush=True)            # 把本次循环的percent赋值给last            last_percent = current_percent

  调用函数的代码如下:

progress_generator = progress_bar(file_size)progress_generator.__next__()#其他代码progress_generator.send(receive_size)

  三、程序的server端与client端的代码如下:

import osimport socketimport json# C:\Users\dell\Desktop\testBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))STATUS_CODE = {        200: "开始发送文件!",        201: "文件不存在!",    }def send_response(conn,status_code,*args,**kwargs):    #制作消息    data = kwargs    data['status_code'] = status_code    data['status_msg'] = STATUS_CODE[status_code]    data['fill'] = ''    #扩展data字典,将file_size键加进去    data.update(kwargs)    #二进制的消息    bytes_data = json.dumps(data).encode('utf-8')    #制作定长报头    if len(bytes_data) < 1024:        # zfill——返回指定长度字符串,原字符串右对齐,前面填充0        data['fill'] = data['fill'].zfill(1024-len(bytes_data))        bytes_data = json.dumps(data).encode('utf-8')    conn.send(bytes_data)def get(conn,addr,filename):    while 1:        if not filename:#空指令,断开链接            print('connection is lost!')            del conn,addr            break        file_path = os.path.join(BASE_DIR,'server',filename)        #如果文件存在        if os.path.isfile(file_path):            #得出文件的大小            file_size = os.stat(file_path).st_size            send_response(conn,200,file_size=file_size)            #开始发送文件            f = open(file_path,'rb')            for line in f:                conn.send(line)            else:                print('文件传输成功!')            f.close()        else:            send_response(conn,201)def run():    whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)    whw_server.bind(('127.0.0.1',9999))    whw_server.listen(5)    print('Listening......')    conn,addr = whw_server.accept()    while 1:        try:            res = conn.recv(8096)            cmds = res.decode('utf-8').split()            print('收到命令:',res.decode('utf-8'))            if cmds[0] == 'get':                get(conn,addr,cmds[1])        except ConnectionResetError:            break    conn.close()if __name__ == '__main__':    run()
server.py
import osimport socketimport json# C:\Users\dell\Desktop\testBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))def progress_bar(total_size, current_percent=0, last_percent=0):    '''进度条功能'''    while 1:        received_size = yield current_percent        current_percent = int(received_size / total_size * 100)        if current_percent > last_percent:            print("*" * int(current_percent / 2) + "{percent}%".format(percent=current_percent), end='\r',                  flush=True)            # 把本次循环的percent赋值给last            last_percent = current_percentdef send_message(whw_sock,filename,**kwargs):    '''给客户端发送报头'''    msg_data = {        'file_name':filename,        'fill':''#做定长    }    msg_data.update(kwargs)    bytes_msg = json.dumps(msg_data).encode('utf-8')    if len(msg_data) < 1024:#定长的报头        msg_data['fill'] = msg_data['fill'].zfill(1024-len(bytes_msg))        bytes_msg = json.dumps(msg_data).encode('utf-8')    whw_sock.send(bytes_msg)def get_response(whw_sock):    """获取服务器端返回的信息"""    data = whw_sock.recv(1024)    return json.loads(data.decode('utf-8'))def get(whw_sock,cmds):    filename = cmds[1]    response = get_response(whw_sock)    # file_size与server端send_response(conn,200,file_size=file_size)对对应    file_size = response.get('file_size')    receive_size = 0    # 进度条功能    progress_generator = progress_bar(file_size)    progress_generator.__next__()    #注意wb方式打开    f = open('%s.download' % filename, 'wb')    # 循环接收    while receive_size < file_size:        if file_size - receive_size < 8192:  # last recv            data = whw_sock.recv(file_size - receive_size)        else:            data = whw_sock.recv(8192)        receive_size += len(data)        f.write(data)        # 打印进度条        progress_generator.send(receive_size)    else:        print('\n')        print('---file [%s] recv done,received size [%s]---' % (filename, file_size))        f.close()        os.replace('%s.download' % filename, filename)def run():    whw_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)    whw_sock.connect(('127.0.0.1',9999))    while 1 :        inp = input('>>>:').strip()        if not inp:            continue        whw_sock.send(inp.encode('utf-8'))        cmds = inp.split()        if cmds[0] == 'get':            get(whw_sock,cmds)if __name__ == '__main__':    run()
client.py

  四、演示如下:

 

转载于:https://www.cnblogs.com/paulwhw/p/9075221.html

你可能感兴趣的文章
BZOJ 2456 mode
查看>>
洛谷 P3975 [TJOI2015]弦论 解题报告
查看>>
seo如何选择自己网站的关键词
查看>>
浅析Java中的final关键字
查看>>
解决linux ssh登陆缓慢问题
查看>>
UOJ33 [UR #2] 树上GCD 【点分治】【容斥原理】【分块】
查看>>
lambda函数,内置map()函数及filter()函数
查看>>
0 在线课堂功能完成—适合做教育项目!!利用Php168的文章模块
查看>>
css3 text-shadow字体阴影讲解
查看>>
架构模式: 领域事件
查看>>
字符串String,StringBuffer和StringBuilder
查看>>
方维分享系统修改,后台一键更新缓存
查看>>
docker一键搭建Nginx+PHP环境(含自动部署命令)
查看>>
Linux文件系统的压缩与打包
查看>>
Ubuntu下安装配置OpenNI,OpenCV
查看>>
MATLAB——null函数
查看>>
XMLHttpRequest对象
查看>>
c语言选项实现
查看>>
Linux 学习
查看>>
WEB小计
查看>>