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实现系统状态监测和故障转移实例方法
Nov 18 Python
使用python生成目录树
Mar 29 Python
Python中判断输入是否为数字的实现代码
May 26 Python
浅谈python3.6的tkinter运行问题
Feb 22 Python
pyqt5利用pyqtDesigner实现登录界面
Mar 28 Python
Python获取命令实时输出-原样彩色输出并返回输出结果的示例
Jul 11 Python
python实现引用其他路径包里面的模块
Mar 09 Python
python matplotlib模块基本图形绘制方法小结【直线,曲线,直方图,饼图等】
Apr 26 Python
Python分析微信好友性别比例和省份城市分布比例的方法示例【基于itchat模块】
May 29 Python
Python random模块的使用示例
Oct 10 Python
python用700行代码实现http客户端
Jan 14 Python
python生成可执行exe控制Microsip自动填写号码并拨打功能
Jun 21 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
openPNE常用方法分享
2011/11/29 PHP
phpMyAdmin出现无法载入 mcrypt 扩展,请检查PHP配置的解决方法
2012/03/26 PHP
php常用的安全过滤函数集锦
2014/10/09 PHP
PHP实现采集中国天气网未来7天天气
2014/10/15 PHP
PHP编程入门的基本语法知识点总结
2016/01/26 PHP
浅谈PHP中try{}catch{}的使用方法
2016/12/09 PHP
PHP安装BCMath扩展的方法
2019/02/13 PHP
jQuery EasyUI API 中文文档 - TimeSpinner时间微调器
2011/10/23 Javascript
offsetHeight在OnLoad中获取为0的现象
2013/07/22 Javascript
jQuery的控件及事件(输入控件及回车事件)使用示例
2013/07/25 Javascript
jquery获取html元素的绝对位置和相对位置的方法
2014/06/20 Javascript
jQuery取消ajax请求的方法
2015/06/09 Javascript
基于JS模仿windows文件按名称排序效果
2016/06/29 Javascript
jQuery实现验证码功能
2017/03/17 Javascript
微信小程序 自定义Toast实例代码
2017/06/12 Javascript
Vue中封装input组件的实例详解
2017/10/17 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
详解微信小程序调起键盘性能优化
2018/07/24 Javascript
基于JS抓取某高校附近共享单车位置 使用web方式展示位置变化代码实例
2019/08/27 Javascript
react实现复选框全选和反选组件效果
2020/08/25 Javascript
举例讲解Python中metaclass元类的创建与使用
2016/06/30 Python
python处理“
2019/06/10 Python
详解pandas DataFrame的查询方法(loc,iloc,at,iat,ix的用法和区别)
2019/08/02 Python
Python3 filecmp模块测试比较文件原理解析
2020/03/23 Python
意大利奢侈品零售商:ilDuomo Novara
2019/09/11 全球购物
为您搜罗全球潮流時尚品牌:HBX
2019/12/04 全球购物
Farfetch中文官网:奢侈品牌时尚购物平台
2020/03/15 全球购物
会计专业大学生职业生涯规划书
2014/02/11 职场文书
护士岗位职责
2014/02/16 职场文书
高中生逃课检讨书
2014/10/10 职场文书
分居协议书范本
2014/11/03 职场文书
2014年财务科工作总结
2014/11/11 职场文书
实习介绍信模板
2015/01/30 职场文书
奖学金个人总结
2015/03/04 职场文书
2015年人事专员工作总结
2015/04/29 职场文书
详解Nginx的超时keeplive_timeout配置步骤
2022/05/25 Servers