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里隐藏的“禅”
Jun 16 Python
python使用marshal模块序列化实例
Sep 25 Python
python获得文件创建时间和修改时间的方法
Jun 30 Python
Python探索之ModelForm代码详解
Oct 26 Python
手把手教你用python抢票回家过年(代码简单)
Jan 21 Python
解决nohup重定向python输出到文件不成功的问题
May 11 Python
Python设计模式之代理模式实例详解
Jan 19 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
Jul 22 Python
python3+django2开发一个简单的人员管理系统过程详解
Jul 23 Python
Django CSRF跨站请求伪造防护过程解析
Jul 31 Python
Xadmin+rules实现多选行权限方式(级联效果)
Apr 07 Python
scrapy框架携带cookie访问淘宝购物车功能的实现代码
Jul 07 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者的疑难问答(1)
2006/10/09 PHP
PHP iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
php模板原理讲解
2013/11/13 PHP
php获取网页上所有链接的方法
2015/04/03 PHP
ThinkPHP中使用Ueditor富文本编辑器
2015/09/02 PHP
使用PHPMailer发送邮件实例
2017/02/15 PHP
PHP中检索字符串的方法分析【strstr与substr_count方法】
2017/02/17 PHP
Laravel 实现密码重置功能
2018/02/23 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
JMenuTab简单使用说明
2008/03/13 Javascript
JQuery实现自定义对话框的代码
2008/06/15 Javascript
JavaScript让IE浏览器event对象符合W3C DOM标准
2009/11/24 Javascript
原生javascript实现图片轮播效果代码
2010/09/03 Javascript
JavaScript 处理Iframe自适应高度(同或不同域名下)
2013/03/29 Javascript
Js日期选择器并自动加入到输入框中示例代码
2013/08/02 Javascript
Javascript 浮点运算精度问题分析与解决
2014/03/26 Javascript
js判断鼠标左、中、右键哪个被点击的方法
2015/01/27 Javascript
js实现新年倒计时效果
2015/12/10 Javascript
纯jQuery实现前端分页功能
2017/03/23 jQuery
JavaScript切换搜索引擎的导航网页搜索框实例代码
2017/06/11 Javascript
element-ui使用导航栏跳转路由的用法详解
2018/08/22 Javascript
详解小程序如何动态绑定点击的执行方法
2019/11/26 Javascript
python+ffmpeg视频并发直播压力测试
2018/03/06 Python
python3+PyQt5泛型委托详解
2018/04/24 Python
Python中的集合介绍
2019/01/28 Python
python按照多个条件排序的方法
2019/02/08 Python
python列表的逆序遍历实现
2020/04/20 Python
Collection和Collections的区别
2016/05/02 面试题
syb养殖创业计划书
2014/01/09 职场文书
西门豹教学反思
2014/02/04 职场文书
红旗方阵解说词
2014/02/12 职场文书
先进集体事迹材料
2014/02/17 职场文书
《盘古开天地》教学反思
2014/02/28 职场文书
党员个人公开承诺书
2014/08/29 职场文书
个性发展自我评价2015
2015/03/09 职场文书
PyTorch 如何检查模型梯度是否可导
2021/06/05 Python