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使用urllib模块开发的多线程豆瓣小站mp3下载器
Jan 16 Python
Python pickle类库介绍(对象序列化和反序列化)
Nov 21 Python
python处理xml文件的方法小结
May 02 Python
python读取并写入mat文件的方法
Jul 12 Python
Python获取时间范围内日期列表和周列表的函数
Aug 05 Python
python 用户交互输入input的4种用法详解
Sep 24 Python
python每5分钟从kafka中提取数据的例子
Dec 23 Python
Django实现将一个字典传到前端显示出来
Apr 03 Python
浅谈Python中的字符串
Jun 10 Python
基于tf.shape(tensor)和tensor.shape()的区别说明
Jun 30 Python
Python的这些库,你知道多少?
Jun 09 Python
python DataFrame中stack()方法、unstack()方法和pivot()方法浅析
Apr 06 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
ftp类(myftp.php)
2006/10/09 PHP
又一个php 分页类实现代码
2009/12/03 PHP
PHP自带函数给数字或字符串自动补齐位数
2014/07/29 PHP
如何通过Apache在本地配置多个虚拟主机
2020/07/29 PHP
图片延迟加载的实现代码(模仿懒惰)
2013/03/29 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
100多个基础常用JS函数和语法集合大全
2017/02/16 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
Bootstrap Table使用整理(四)之工具栏
2017/06/09 Javascript
详解基于angular-cli配置代理解决跨域请求问题
2017/07/05 Javascript
jQuery 同时获取多个标签的指定内容并储存为数组
2018/11/20 jQuery
jQuery加PHP实现图片上传并提交的示例代码
2020/07/16 jQuery
vue组件中实现嵌套子组件案例
2020/08/31 Javascript
原生js实现点击按钮复制内容到剪切板
2020/11/19 Javascript
[42:32]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第二局
2016/02/27 DOTA
[01:07:41]IG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
调试Python程序代码的几种方法总结
2015/04/28 Python
DES加密解密算法之python实现版(图文并茂)
2018/12/06 Python
Python multiprocessing多进程原理与应用示例
2019/02/28 Python
Python简单处理坐标排序问题示例
2019/07/11 Python
分享30个新鲜的CSS3打造的精美绚丽效果(附演示下载)
2012/12/28 HTML / CSS
HTML5 canvas基本绘图之图形组合
2016/06/27 HTML / CSS
大韩航空官方网站:Korean Air
2017/10/25 全球购物
新加坡最受追捧的体验平台:Hapz
2018/01/01 全球购物
美国生鲜及杂货电商:FreshDirect
2018/01/29 全球购物
来自Ocado的宠物商店:Fetch
2018/07/10 全球购物
英国现代市场:ARKET
2019/04/10 全球购物
亚洲航空公司官方网站:AirAsia
2019/11/25 全球购物
机械制造专业毕业生求职信
2014/03/02 职场文书
食品业务员岗位职责
2014/03/18 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
小学教学工作总结2015
2015/05/13 职场文书
2016领导干部廉洁从政心得体会
2016/01/19 职场文书
中学语文教学反思
2016/02/16 职场文书
2019广播稿怎么写
2019/04/17 职场文书
ECharts transform数据转换和dataZoom在项目中使用
2022/12/24 Javascript