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求斐波那契数列示例分享
Feb 14 Python
详解Python中的Cookie模块使用
Jul 06 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
Nov 30 Python
Django中使用Celery的方法示例
Nov 29 Python
Python设计模式之命令模式原理与用法实例分析
Jan 11 Python
Python脚本修改阿里云的访问控制列表的方法
Mar 08 Python
Python后台开发Django的教程详解(启动)
Apr 08 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
Sep 07 Python
python英语单词测试小程序代码实例
Sep 09 Python
Pandas操作CSV文件的读写实现方法
Nov 13 Python
Django 404、500页面全局配置知识点详解
Mar 10 Python
详解如何在pyqt中通过OpenCV实现对窗口的透视变换
Sep 20 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
使用php将某个目录下面的所有文件罗列出来的方法详解
2013/06/21 PHP
Thinkphp通过一个入口文件如何区分移动端和PC端
2017/04/18 PHP
PHP高精确度运算BC函数库实例详解
2017/08/15 PHP
Yii框架Session与Cookie使用方法示例
2019/10/14 PHP
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
JS中多步骤多分步的StepJump组件实例详解
2016/04/01 Javascript
js一维数组、多维数组和对象的混合使用方法
2016/04/03 Javascript
Node.js DES加密的简单实现
2016/07/07 Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
2017/01/17 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
ES6学习教程之Map的常用方法总结
2017/08/03 Javascript
前端把html表格生成为excel表格的实例
2017/09/19 Javascript
vue实现验证码输入框组件
2017/12/14 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
浅谈在不使用ssr的情况下解决Vue单页面SEO问题(2)
2018/11/08 Javascript
使用pm2自动化部署node项目的方法步骤
2019/01/28 Javascript
M2实现Nodejs项目自动部署的方法步骤
2019/05/05 NodeJs
常见的浏览器存储方式(cookie、localStorage、sessionStorage)
2019/05/07 Javascript
javascript关于“时间”的一次探索
2019/07/24 Javascript
详细介绍解决vue和jsp结合的方法
2020/02/06 Javascript
jQuery HTML设置内容和属性操作实例分析
2020/05/20 jQuery
Flexible.js可伸缩布局实现方法详解
2020/11/13 Javascript
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
1分钟快速生成用于网页内容提取的xslt
2018/02/23 Python
PyQt5每天必学之QSplitter实现窗口分隔
2018/04/19 Python
Python全排列操作实例分析
2018/07/24 Python
Python中的引用知识点总结
2019/05/20 Python
Python Numpy库常见用法入门教程
2020/01/16 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
2020/07/21 Python
Vero Moda西班牙官方购物网站:丹麦BESTSELLER旗下知名女装品牌
2018/04/27 全球购物
大学生四个方面的自我评价
2013/09/19 职场文书
面试求职的个人自我评价
2013/11/16 职场文书
小学教师师德师风演讲稿
2014/08/22 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书
关于vue中如何监听数组变化
2021/04/28 Vue.js
python绘图subplots函数使用模板的示例代码
2021/04/30 Python