python利用socketserver实现并发套接字功能


Posted in Python onJanuary 26, 2018

本文实现利用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)

自己可以设置一个多用户登录,然后测试,用户下载同一个文件,分别存入每个用户自己的家目录下面,效果更好。

当然现在也能测试,开启两个客户端同时下载文件。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python通过解析网页实现看报程序的方法
Aug 04 Python
Python编程中归并排序算法的实现步骤详解
May 04 Python
python检查URL是否正常访问的小技巧
Feb 25 Python
Python3 伪装浏览器的方法示例
Nov 23 Python
python处理两种分隔符的数据集方法
Dec 12 Python
对python中的six.moves模块的下载函数urlretrieve详解
Dec 19 Python
Python完成毫秒级抢淘宝大单功能
Jun 06 Python
python适合人工智能的理由和优势
Jun 28 Python
Python3 shutil(高级文件操作模块)实例用法总结
Feb 19 Python
python 中不同包 类 方法 之间的调用详解
Mar 09 Python
解决jupyter运行pyqt代码内核重启的问题
Apr 16 Python
浅谈cv2.imread()和keras.preprocessing中的image.load_img()区别
Jun 12 Python
Django的HttpRequest和HttpResponse对象详解
Jan 26 #Python
Python编程实现的简单神经网络算法示例
Jan 26 #Python
Django使用httpresponse返回用户头像实例代码
Jan 26 #Python
Django rest framework基本介绍与代码示例
Jan 26 #Python
Python实现PS图像调整之对比度调整功能示例
Jan 26 #Python
Python实现PS滤镜特效之扇形变换效果示例
Jan 26 #Python
修复CentOS7升级Python到3.6版本后yum不能正确使用的解决方法
Jan 26 #Python
You might like
在“咖啡之国”感受咖啡文化
2021/03/03 咖啡文化
php中计算程序运行时间的类代码
2012/11/03 PHP
php文件类型MIME对照表(比较全)
2016/10/07 PHP
详解PHP的抽象类和抽象方法以及接口总结
2019/03/15 PHP
初学prototype,发个JS接受URL参数的代码
2006/09/25 Javascript
一个轻量级的javascript库 pj介绍
2010/12/19 Javascript
jQuery学习笔记 获取jQuery对象
2012/09/19 Javascript
JavaScript每天必学之事件
2016/09/18 Javascript
Bootstrap3 图片(响应式图片&amp;图片形状)
2017/01/04 Javascript
NW.js 简介与使用方法
2018/02/01 Javascript
vue router+vuex实现首页登录验证判断逻辑
2018/05/17 Javascript
JavaScript错误处理操作实例详解
2019/01/04 Javascript
ES6使用 Array.includes 处理多重条件用法实例分析
2020/03/02 Javascript
webpack 动态批量加载文件的实现方法
2020/03/19 Javascript
taro 实现购物车逻辑的实例代码
2020/06/05 Javascript
微信小程序实现发微博功能的示例代码
2020/06/24 Javascript
[08:08]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY
2014/06/25 DOTA
[00:48]食人魔魔法师至宝“金鹏之幸”全新模型和自定义特效展示
2019/12/19 DOTA
python中的格式化输出用法总结
2016/07/28 Python
python实现SOM算法
2018/02/23 Python
Python3.5.3下配置opencv3.2.0的操作方法
2018/04/02 Python
Python学习笔记之图片人脸检测识别实例教程
2019/03/06 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
python的pytest框架之命令行参数详解(下)
2019/06/27 Python
Python实现i人事自动打卡的示例代码
2020/01/09 Python
Python爬虫实例——爬取美团美食数据
2020/07/15 Python
纯css3实现鼠标经过图片显示描述的动画效果
2014/09/01 HTML / CSS
万宝龙英国官网:Montblanc手表、书写工具、皮革和珠宝
2018/10/16 全球购物
艺术节主持词
2014/04/02 职场文书
小学语文教学经验交流材料
2014/06/02 职场文书
实习单位证明范例
2014/11/17 职场文书
党员自评材料范文
2014/12/17 职场文书
教师考核鉴定意见
2015/06/05 职场文书
《走遍天下书为侣》教学反思
2016/02/22 职场文书
祝福语集锦:送给闺蜜的生日祝福语
2019/10/08 职场文书
SpringBoot中HttpSessionListener的简单使用方式
2022/03/17 Java/Android