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写的一个squid访问日志分析的小程序
Sep 17 Python
python遍历数组的方法小结
Apr 30 Python
深入学习python的yield和generator
Mar 10 Python
Python实现小数转化为百分数的格式化输出方法示例
Sep 20 Python
Python结合ImageMagick实现多张图片合并为一个pdf文件的方法
Apr 24 Python
解决python 自动安装缺少模块的问题
Oct 22 Python
Python检测数据类型的方法总结
May 20 Python
Django urls.py重构及参数传递详解
Jul 23 Python
django数据关系一对多、多对多模型、自关联的建立
Jul 24 Python
Python爬虫库BeautifulSoup获取对象(标签)名,属性,内容,注释
Jan 25 Python
django实现将后台model对象转换成json对象并传递给前端jquery
Mar 16 Python
Python PyQt5整理介绍
Apr 01 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转义输出HTML到JavaScript
2015/03/27 PHP
Javascript实现关联数据(Linked Data)查询及注意细节
2013/02/22 Javascript
jquery图片放大功能简单实现
2013/08/01 Javascript
Jquery解析json字符串及json数组的方法
2015/05/29 Javascript
javascript事件委托的方式绑定详解
2015/06/10 Javascript
JS模式之单例模式基本用法
2015/06/30 Javascript
JavaScript学习笔记之DOM基础 2.4
2015/08/14 Javascript
每天一篇javascript学习小结(面向对象编程)
2015/11/20 Javascript
JavaScript动态设置div的样式的方法
2015/12/26 Javascript
AngularJS中的Directive实现延迟加载
2016/01/25 Javascript
jquery遍历json对象集合详解
2016/05/18 Javascript
AngularJS实现按钮提示与点击变色效果
2016/09/07 Javascript
js控制文本框禁止输入特殊字符详解
2017/04/07 Javascript
vue-cli入门之项目结构分析
2017/04/20 Javascript
Vue 组件修改根实例的数据的方法
2019/04/02 Javascript
优雅地使用loading(推荐)
2019/04/20 Javascript
layui数据表格跨行自动合并的例子
2019/09/02 Javascript
javascript实现图片轮换动作方法
2020/08/07 Javascript
Python统计文件中去重后uuid个数的方法
2015/07/30 Python
python利用socketserver实现并发套接字功能
2018/01/26 Python
Selenium的使用详解
2018/10/19 Python
pytorch 调整某一维度数据顺序的方法
2018/12/08 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
2019/02/16 Python
python RC4加密操作示例【测试可用】
2019/09/26 Python
python简单利用字典破解zip文件口令
2020/09/07 Python
pandas处理csv文件的方法步骤
2020/10/16 Python
使用numpngw和matplotlib生成png动画的示例代码
2021/01/24 Python
h5页面背景图很长要有滚动条滑动效果的实现
2021/01/27 HTML / CSS
美国购买舞会礼服网站:Couture Candy
2019/12/29 全球购物
捐款倡议书格式范文
2014/05/14 职场文书
2014年个人售房协议书
2014/10/30 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
关于清明节的演讲稿2015
2015/03/18 职场文书
2016年优秀教师先进事迹材料
2016/02/26 职场文书
十大最强飞行系宝可梦,BUG燕上榜,第二是飞行系王者
2022/03/18 日漫
Java实现带图形界面的聊天程序
2022/06/10 Java/Android