python利用socketserver实现并发套接字功能
本文实现利用python的socketserver这个强大的模块实现套接字的并发,具体内容如下
目录结构如下:
测试文件请放在server_file文件夹里面
server.py
#!/usr/bin/env python
# -*- coding: gbk -*-
# @Version : Python 3.5.2
# @Time : 2018/1/24 10:29
# @Author : Ncp
# @File : server.py
# @Software: PyCharm
import json
import time
import hashlib
import struct
import os
from socketserver import *
FILE_PATH = os.path.dirname(os.path.abspath(__file__))+'\\server_file'
class MYserver(BaseRequestHandler): # 设置一个类,基础BaseRequestHandler这个类
def handle(self): # 这个方法下添加通信功能(和上面创建类一样,这是socketserver的固定模式)
print(self.client_address)
'''
:functions: 使用socketserver的并发套接字,提供客户端下载文件,并对文件进行MD5加密
'''
while True:
try:
data = self.request.recv(1024)
data_recv = data.decode('gbk').split()
if not os.path.exists(FILE_PATH+r'\%s' %data_recv[1]):
self.request.send('file is not found'.encode('gbk'))
continue
else:
data = self.request.send('1'.encode('gbk')) # 这里发现小问题,不回复一个信息的话,发送给客户端的包头居然成了没有封装
FILE_SIZE = os.path.getsize(FILE_PATH+r'\%s' %data_recv[1])
with open(FILE_PATH+r'\%s' %data_recv[1],'rb')as f:
hash_file = f.read()
m = hashlib.md5()
m.update(hash_file)
m_hex = m.hexdigest()
file_header = {'filename':data_recv[1],
'filesize':FILE_SIZE,
'md5':m_hex,
'time':time.strftime('%Y-%m-%d-%X',time.localtime())
}
# 包头信息序列化
file_header_dump = json.dumps(file_header)
# 编译成2进制
file_header_bytes = file_header_dump.encode('gbk')
# 封装报头
file_header_struct = struct.pack('i',len(file_header_bytes))
# 发送报头
self.request.send(file_header_struct)
# 发送报文内容
self.request.send(file_header_bytes)
# 发送文件数据
send_size = 0
with open(FILE_PATH+r'\%s' %data_recv[1] , 'rb')as f:
for i in f:
self.request.send(i)
send_size += len(i) # 这里后续可以拓展一个进度或者网速显示功能
except Exception:
self.request.close()
if __name__ == '__main__':
server = ThreadingTCPServer(('127.0.0.1',8080),MYserver) # windows下只能开启多线程
server.serve_forever()
client.py
#!/usr/bin/env python
# -*- coding: gbk -*-
# @Version : Python 3.5.2
# @Time : 2018/1/24 10:29
# @Author : Ncp
# @File : client.py
# @Software: PyCharm
from socket import *
import os,sys
import hashlib
import struct
import math
import json
FILE_PATH = os.path.dirname(os.path.abspath(__file__))+'\\client_file'
# 显示下载进度条功能,可以拓展为显示下载速度(提示,因为每次传输4096个字节,那么下载网速为KB/S,1KB个字节=1024B(字节),那么1s传输了多少个字节呢?)
def progress(recvd, total):
fraction = '{:.0%}'.format(recvd / total)
sys.stdout.write('\r[%-30s] %s' % ('#' * int(math.floor(recvd * 30 / total)), fraction))
sys.stdout.flush()
if recvd == total:
sys.stdout.write('\n')
# 主函数
def run(ip,addr):
client = socket(AF_INET,SOCK_STREAM)
client.connect((ip,addr))
while True:
user_input = input('>>').strip()
cmd = user_input.split()
if len(cmd) != 2:
print('input format is error please use:get xx')
continue
if cmd[0] == 'get':
client.send(user_input.encode('gbk'))
data = client.recv(1024)
data_recv = data.decode('gbk')
if data_recv == 'file is not found':
print(data_recv)
continue
else:
print('commands is not found')
continue
# 收包头,然后一系列处理
header = client.recv(4)
if not header:break
header_json_len = struct.unpack('i', header)[0]
header_json_bytes = client.recv(header_json_len)
header_josn = header_json_bytes.decode('gbk')
header_dic = json.loads(header_josn)
# 去除包头内容进行下载
print(header_dic)
data_len = header_dic['filesize']
data_file = header_dic['filename']
data_md5 = header_dic['md5']
recv_size = 0
with open(FILE_PATH+r'\%s' %data_file,'wb')as fw:
while recv_size < data_len:
recv_data = client.recv(4096)
recv_size += len(recv_data)
fw.write(recv_data)
progress(recv_size,data_len)
print('Download completion, start validation')
# 收到文件后,读取文件进行加密,看是否与服务端下载的文件一致!
with open(FILE_PATH+r'\%s' %data_file,'rb')as fr:
data_total = fr.read()
m = hashlib.md5()
m.update(data_total)
m_hex = m.hexdigest()
if m_hex == data_md5:
print('文件验证通过')
else:
print('文件损坏,删除文件')
os.remove(FILE_PATH+r'\%s' %data_file)
if __name__ == '__main__':
run('127.0.0.1',8080)
自己可以设置一个多用户登录,然后测试,用户下载同一个文件,分别存入每个用户自己的家目录下面,效果更好。
当然现在也能测试,开启两个客户端同时下载文件。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
数据分析在当今信息时代发挥着重要作用。单因素方差分析(One-Way ANOVA)是一种关键的统计方法,用于比较三个或更多独立样本组 ...
2025-04-25CDA持证人简介: 居瑜 ,CDA一级持证人国企财务经理,13年财务管理运营经验,在数据分析就业和实践经验方面有着丰富的积累和经 ...
2025-04-25在当今数字化时代,数据分析师的重要性与日俱增。但许多人在踏上这条职业道路时,往往充满疑惑: 如何成为一名数据分析师?成为 ...
2025-04-24以下的文章内容来源于刘静老师的专栏,如果您想阅读专栏《刘静:10大业务分析模型突破业务瓶颈》,点击下方链接 https://edu.cda ...
2025-04-23大咖简介: 刘凯,CDA大咖汇特邀讲师,DAMA中国分会理事,香港金管局特聘数据管理专家,拥有丰富的行业经验。本文将从数据要素 ...
2025-04-22CDA持证人简介 刘伟,美国 NAU 大学计算机信息技术硕士, CDA数据分析师三级持证人,现任职于江苏宝应农商银行数据治理岗。 学 ...
2025-04-21持证人简介:贺渲雯 ,CDA 数据分析师一级持证人,互联网行业数据分析师 今天我将为大家带来一个关于用户私域用户质量数据分析 ...
2025-04-18一、CDA持证人介绍 在数字化浪潮席卷商业领域的当下,数据分析已成为企业发展的关键驱动力。为助力大家深入了解数据分析在电商行 ...
2025-04-17CDA持证人简介:居瑜 ,CDA一级持证人,国企财务经理,13年财务管理运营经验,在数据分析实践方面积累了丰富的行业经验。 一、 ...
2025-04-16持证人简介: CDA持证人刘凌峰,CDA L1持证人,微软认证讲师(MCT)金山办公最有价值专家(KVP),工信部高级项目管理师,拥有 ...
2025-04-15持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。在实际生活中,我们可能会 ...
2025-04-14在 Python 编程学习与实践中,Anaconda 是一款极为重要的工具。它作为一个开源的 Python 发行版本,集成了众多常用的科学计算库 ...
2025-04-14随着大数据时代的深入发展,数据运营成为企业不可或缺的岗位之一。这个职位的核心是通过收集、整理和分析数据,帮助企业做出科 ...
2025-04-11持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。 本次分享我将以教培行业为 ...
2025-04-11近日《2025中国城市长租市场发展蓝皮书》(下称《蓝皮书》)正式发布。《蓝皮书》指出,当前我国城市住房正经历从“增量扩张”向 ...
2025-04-10在数字化时代的浪潮中,数据已经成为企业决策和运营的核心。每一位客户,每一次交易,都承载着丰富的信息和价值。 如何在海量客 ...
2025-04-09数据是数字化的基础。随着工业4.0的推进,企业生产运作过程中的在线数据变得更加丰富;而互联网、新零售等C端应用的丰富多彩,产 ...
2025-04-094月7日,美国关税政策对全球金融市场的冲击仍在肆虐,周一亚市早盘,美股股指、原油期货、加密货币、贵金属等资产齐齐重挫,市场 ...
2025-04-08背景 3月26日,科技圈迎来一则重磅消息,苹果公司宣布向浙江大学捐赠 3000 万元人民币,用于支持编程教育。 这一举措并非偶然, ...
2025-04-07在当今数据驱动的时代,数据分析能力备受青睐,数据分析能力频繁出现在岗位需求的描述中,不分岗位的任职要求中,会特意标出“熟 ...
2025-04-03