6.28自我总结

客户端与服务器之间文件传输断电续传

`通过判断文件大小,以及文件在读取中的指针位置的调整来解决断电续传问题'

1.程序目录

E:/断电续传
|___bil
| |___common.py #公共方法
|___conf
| |___logger_setting.py #存日志的格式
| |___setting.py #一些常量
|___db
| |___client #程序端存文件的文件夹
| |___logger #存日志的文件夹
| |___sever #服务端存文件的文件夹
|___requirements.txt #方便别人导入库
|___test.py #程序写的时候有些东西需要单独拿出来试试
|___客户端.py
|___服务端.py

2.程序思路

  • 第一步:我们什么都不懂,但是有几个模块肯定会有一个是conf中的setting来存一些常量

  • 第二步:我们也需要一个db文件来存内容

  • 第三步:我们要也有个bil存一些可能会出现的公共方法,可以精简代码

  • 第四部:生成requirements.txt文件,方便其他人用模板时候可以一键安装需要的模板

    ​ requirements的自动生成方式cmd中输入pip freeze > requirements.txt

    ​ 然后清空下内容,如果有用到第三方库什么的可以写进去方便别人安装

  • 第五步:根据功能然后进行添加,有些常量丢setting里面,公共方法丢common里面去

3.程序内容

1.conf

1.setting.py

import os

#项目文件夹路径
PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#文件存放夹路径
DB_PATH = os.path.join(PATH,'db')
#客户端存放路径
CLIENT_PATH = os.path.join(PATH,'db','client')
#服务端存放路径
SEVER_PATH = os.path.join(PATH,'db','sever')
#日志存放路径
LOGGER_PATH = os.path.join(PATH,'db','logger') #服务端PROT
IP = '127.0.0.1'
#服务端端口
PROT = 8000

2.logger_setting.py

import os
import logging.config
#函数上面部分要根据你程序进行修改
# 定义三种日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' # 其中name为getLogger()指定的名字;lineno为调用日志输出函数的语句所在的代码行
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
# 定义日志输出格式 结束 # log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {}, # filter可以不定义
'handlers': {
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'default': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': 1, # 日志文件
'maxBytes': 1024 * 1024 * 5, # 日志大小 5M (*****)
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
# logging.getLogger(__name__)拿到的logger配置。如果''设置为固定值logger1,则下次导入必须设置成logging.getLogger('logger1')
'': {
# 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'handlers': ['default', 'console'],
'level': 'DEBUG',
'propagate': False, # 向上(更高level的logger)传递
},
},
}

2.bil

common.py

from conf.setting import *
import struct
from conf.logger_setting import *
import logging.config
import datetime #获取文件路径下的子文件的目录列表
def get_flie_lis(path):
'''获取文件路径下的子文件的目录列表''' if os.path.exists(path):return os.listdir(path)
return False #获取客文件的大小
def get_flie_size(filename,filefrom):
'''获取客文件的大小'''
path = os.path.join(DB_PATH,filefrom,filename) if os.path.exists(path): return os.path.getsize(path)
return 0 #内容大小进行压缩,int格式内容进行压缩成4个字符
def zip_data(data:int):
'''内容大小进行压缩,int格式内容进行压缩成4个字符'''
return struct.pack('i',data) #解压缩
def uncompress(zipflie):
'''解压缩压缩文件'''
return struct.unpack('i',zipflie)[0] #根据文件路径读取文件大小以及文件的内容变成个生成器
def get_file_size_data(path):
'''根据文件路径读取文件大小以及文件的内容变成个生成器'''
#生成文件大小
file_name = path.split('\\')[-1]
file_size = get_flie_size(file_name,'client') size = os.path.getsize(path)
with open(path,'rb') as fr:
fr.seek(file_size,0)
while True:
data = fr.read(10240)
if data == bytes():return True
yield size,data #日志
def load_my_logging_cfg(name):
'''生成随着时间生成文件夹日志'''
#生成日志保存路径
time = str(datetime.datetime.now())
time = time.split(' ')[0]
path = os.path.join(LOGGER_PATH,time)
if not os.path.exists(path):os.mkdir(path)
file_path = os.path.join(path, f'{name}.log') #修改定义格式中的地址
logger_fromat = LOGGING_DIC
logger_fromat['handlers']['default']['filename'] =file_path logging.config.dictConfig(logger_fromat) # 导入上面定义的logging配置
logger = logging.getLogger(name) # 生成一个log实例
logger.info(f'{name} works!') # 记录该文件的运行状态可以自己修改

3.db

可以先新建好这三个文件夹,也可以用os.path.exists(path)判断路径来生成

4.服务端.py

from socket import *
from conf.setting import IP,PROT,SEVER_PATH
from bil.common import *
from conf.setting import * load_my_logging_cfg('sever')
#生成服务器
sever = socket()
sever.bind((IP,PROT))
sever.listen(5) print('start....')
#消息的传输
while True:
#建立连接
conn,addr = sever.accept() while True:
try:
#进行文件的传输
#接受1
request = conn.recv(1024)
#获得客户端目录下的所有文件名称,并且转换成list
flie_list = get_flie_lis(SEVER_PATH) #列表内容进行压缩
flie_list_str_len = zip_data(len(str(flie_list))) #发送列表字符串格式大小
conn.send(flie_list_str_len)
# 发送列表的字符串
conn.send(str(flie_list).encode('utf8')) #接收文件名
file_name = conn.recv(1024).decode('utf8') #拼接文件路径
file_path = os.path.join(SEVER_PATH,file_name) #判断文件是不是客户端已经下载完成了
file_name = file_path.split('\\')[-1]
#为了防止客户端因为没有文件而报错,且没有文件把他大小设置成0
try:
file_size = get_flie_size(file_name, 'client')
except Exception:
file_size = 0
sever_file_size = get_flie_size(file_name, 'sever') print(file_size,sever_file_size,file_size == sever_file_size)
# 生成文件内容与文件大小的生成器
if file_size != sever_file_size:
count = 0
for size,file_data in get_file_size_data(file_path):
#就第一次发送文件大小
if count == 0: conn.send(zip_data(size))
print(str(zip_data(size)).encode('utf8'))
print(file_data)
conn.send(file_data)
count += 1
else:
print(1)
#文件已经传输好了客户端有这个文件了
conn.send(zip_data(0))
except:
break
conn.close()

5.客户端.py

from socket import *
from bil.common import *
from conf.setting import * load_my_logging_cfg('client')
#生成客户端
client = socket() #与服务端建立连接
client.connect(('127.0.0.1',8000)) #消息的传输
while True:
#自动发送请求获取
client.send(b'1') #接受文件目录大小
list_st_size = client.recv(4)
#根据文件目录大小获取列表的字符串内容
data = client.recv(uncompress(list_st_size))
#将文件目录进行打印
file_list = eval(data.decode('utf8'))
print('请选择你要打印文件') for file_index,file_name in enumerate(file_list):
print(f'文件编号{file_index}文件名{file_name}') while True:
chiose = input('请选择你要下载文件的编号:')
try:
chiose_file_name = file_list[int(chiose)]
break
except Exception:
print('序号不存在')
continue #发送选择的文件名
chiose_file_name = file_list[int(chiose)]
print(chiose_file_name)
client.send(str(chiose_file_name).encode('utf8')) #接收文件大小 file_size = uncompress(client.recv(4))
print(file_size) if file_size != 0:
#初始下载文件大小
client_file_size = get_flie_size(chiose_file_name,'clien') #下载文件
path = os.path.join(CLIENT_PATH,chiose_file_name)
print(client_file_size)
print(file_size)
while client_file_size <file_size: data = client.recv(10240)
client_file_size += 10240
with open(path,'ab') as fa:
fa.write(data) #打印进度条
if client_file_size < file_size:
schedule = int((client_file_size/file_size)*100)
#为了好看加了颜色进去
print("\r",f'[\033[1;31;40m%-{schedule}s%-3s\033[0m%-{100-schedule}s' % ('', f'{schedule}%', ''),end=']') print("\r",f'[\033[1;31;40m%-100s%-3s\033[0m%-0s' % ('', '100%', ''),end='')
print('')
else:
print('')
print('文件已经下载好了')
chiose_end = input('输入Q退出下载,输入其他继续下载')
if chiose_end =='Q' :break

有不足的地方请指出来,谢谢,这是我在写程序中的总结,这是我学习python刚刚好第二个月后的写的程序

python -服务器与客户端断电续传程序详细介绍的更多相关文章

  1. android81 多线程下载和断电续传

    package com.itheima.multithreaddownload; import java.io.BufferedReader; import java.io.File; import ...

  2. Android中FTP服务器、客户端搭建以及SwiFTP、ftp4j介绍

    本文主要内容: 1.FTP服务端部署---- 基于Android中SwiFTP开源软件介绍: 2.FTP客户端部署 --- 基于ftp4j开源jar包的客户端开发 : 3.使用步骤 --- 如何测试我 ...

  3. 【python之路35】FTP文件断电续传作业

    开发一个支持多用户在线FTP程序: 要求: 1.用户MD5加密认证 2.允许同时多用户登陆(socketserver) 3.执行命令 4.上传文件 文件传输过程中显示进度条 支持文件的断点续传

  4. IceGrid 用于Python服务器和客户端通信——参数传递

    本篇介绍如何用IceGrid建立python多机通信,传递比较复杂的参数 Ice代码:Demo.ice #ifndef TOS_ICE_COMMON #define TOS_ICE_COMMON mo ...

  5. windows下GitHub的安装、配置以及项目的上传过程详细介绍

    概要 本文主要介绍了在Win10系统中安装Github终端.如何配置安装好的Git终端以及如何利用Git终端将自己的项目上传到远程服务器中 操作必备 win10系统电脑一台.良好的互联网连接.GitH ...

  6. HTML5文件上传器,纯脚本无插件的客户端文件上传器---Uploader 文件上传器类

    概述 客户端完全基于JavaScript的 浏览器文件上传器,不需要任何浏览器插件,但需要和jQuery框架协同工作,支持超大文件上传,其算法是将一个超大文件切片成N个数据块依次提交给服务 端处理,由 ...

  7. window系统下SVN服务器和客户端的搭建和使用

    SVN服务器下载地址: http://subversion.apache.org/packages.html 这里我选用VisualSVN server 服务端和 TortoiseSVN客户端搭配使用 ...

  8. 【转】Linux环境搭建FTP服务器与Python实现FTP客户端的交互介绍

    Linux环境搭建FTP服务器与Python实现FTP客户端的交互介绍 FTP 是File Transfer Protocol(文件传输协议)的英文简称,它基于传输层协议TCP建立,用于Interne ...

  9. python web编程-CGI帮助web服务器处理客户端编程

    这几篇博客均来自python核心编程 如果你有任何疑问,欢迎联系我或者仔细查看这本书的地20章 另外推荐下这本书,希望对学习python的同学有所帮助 概念预热 eb客户端通过url请求web服务器里 ...

随机推荐

  1. 论文阅读计划2(Deep Joint Rain Detection and Removal from a Single Image)

    Deep Joint Rain Detection and Removal from a Single Image[1] 简介:多任务全卷积从单张图片中去除雨迹.本文在现有的模型上,开发了一种多任务深 ...

  2. Linux目录结构及文件操作

    Linux文件目录遵循FHS标准 绝对路径:从根目录开始的路径:相对目录:从当前路径开始的路径 .表示当前目录,..表示上级目录,~表示当前用户的home目录,pwd获得当前绝对路径 新建文件 tou ...

  3. 程序员该如何过好他的整个职业生涯?(最重要的是你得一直往前走。拐点不是你的工资。想起很久前有个人说我“逻辑性”比较强)good

    作者|池建强 编辑|小智   戳阅读原文,获得短信提醒,不错过下次InfoQ大咖说直播! 1 写在前面 加入极客邦的第一天就被拉到了「大咖说」的现场,这也是我始料未及的事情.从锤子科技正式离职之后,我 ...

  4. Windows完成端口与猪肉佬

    首先应该说明的是,我也是第一次使用完成端口.虽然以前偶尔在网上看到完成端口的文章和代码,但真正自己动手写还是第一次,不过我这个人有个特点就是大胆,例如没有写那个界面编程系列前,其实我甚至不知道原来一个 ...

  5. WebRequest请求错误(服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF)

    WebRequest请求错误(服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF)解决办法,天津config文件,增加一个配置如下 <?x ...

  6. Nginx学习笔记---服务与集群

    一.集群 什么是集群 服务器架构集群:多台服务器组成的响应式大并发,高数据量访问的架构体系. 特点: (1)成本高 (2)能够降低单台服务器的压力,使用流量平均分配到多台服务器 (3)使网站服务架构更 ...

  7. Hyperledger Fabric1.4的多机部署

    之前的文章深入解析Hyperledger Fabric启动的全过程主要讲解了Fabric的网络搭建,以及启动的整体流程,但是都是通过单机完成的.而区块链本身就是去中心化的,所以最终还是要完成Fabri ...

  8. spring 5.x 系列第7篇 —— 整合Redis客户端 Jedis和Redisson (xml配置方式)

    文章目录 一.说明 1.1 Redis 客户端说明 1.2 Redis可视化软件 1.3 项目结构说明 1.3 依赖说明 二.spring 整合 jedis 2.1 新建基本配置文件 2.2 单机配置 ...

  9. angular安装

    安装时间:20190703安装环境:win10 1 安装Nodejs 1.1 下载地址:https://nodejs.org/en/ 1.2 下载完成之后双击安装,安装完成之后无需配置环境变量(安装的 ...

  10. 【python3两小时根本不够】入门笔记04:线程+Lock安全同步

    有了简单爬虫,但是效率实在是太慢,于是决定启用线程进行爬取数据 但是对于临界资源的定义不好把握,思路如下: 1.定义队列(Queue的数据结构,List也可,安全性待考究) demo:https:// ...