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 08 Python
python difflib模块示例讲解
Sep 13 Python
基于Django filter中用contains和icontains的区别(详解)
Dec 12 Python
Python3.遍历某文件夹提取特定文件名的实例
Apr 26 Python
python ddt数据驱动最简实例代码
Feb 22 Python
python实现弹窗祝福效果
Apr 07 Python
python实现坦克大战游戏 附详细注释
Mar 27 Python
python对数组进行排序,并输出排序后对应的索引值方式
Feb 28 Python
Python3以GitHub为例来实现模拟登录和爬取的实例讲解
Jul 30 Python
彻底解决Python包下载慢问题
Nov 15 Python
Python第三方库安装缓慢的解决方法
Feb 06 Python
如何在向量化NumPy数组上进行移动窗口
May 18 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
JAVA/JSP学习系列之七
2006/10/09 PHP
yii操作cookie实例简介
2014/07/09 PHP
php搜索文件程序分享
2015/10/30 PHP
laravel利用中间件做防非法登录和权限控制示例
2019/10/21 PHP
Thinkphp5框架异常处理操作实例分析
2020/06/03 PHP
jQuery TextBox自动完成条
2009/07/22 Javascript
Jquery + Ajax调用webService实例代码(asp.net)
2010/08/27 Javascript
js自动生成对象的属性示例代码
2013/10/28 Javascript
javascript:FF/Chrome与IE动态加载元素的区别说明
2014/01/26 Javascript
javascript页面渲染速度测试脚本分享
2014/04/15 Javascript
做web开发 先学JavaScript
2014/12/12 Javascript
js实现点击链接后窗口缩小并居中的方法
2015/03/02 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
2015/08/07 Javascript
javascript封装简单实现方法
2015/08/11 Javascript
javascript replace()第二个参数为函数时的参数用法
2016/12/26 Javascript
使用veloticy-ui生成文字动画效果
2018/02/08 Javascript
react-native-video实现视频全屏播放的方法
2018/03/19 Javascript
判断iOS、Android以及PC端的示例代码
2018/11/15 Javascript
微信小程序时间戳转日期的详解
2019/04/30 Javascript
详解JavaScript之ES5的继承
2020/07/08 Javascript
k8s node节点重新加入master集群的实现
2021/02/22 Javascript
[02:18]《我与DAC》之工作人员:为了热爱DOTA2的玩家们
2018/03/28 DOTA
python实现随机森林random forest的原理及方法
2017/12/21 Python
对Python生成汉字字库文字,以及转换为文字图片的实例详解
2019/01/29 Python
Django数据库类库MySQLdb使用详解
2019/04/28 Python
python Elasticsearch索引建立和数据的上传详解
2019/08/04 Python
Python tkinter常用操作代码实例
2020/01/03 Python
为什么黑客都用python(123个黑客必备的Python工具)
2020/01/31 Python
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
运动会入场词100字
2014/02/06 职场文书
市场营销工作计划书
2014/09/15 职场文书
公司出差管理制度范本
2015/08/05 职场文书
资产移交协议书
2016/03/24 职场文书
小公司融资,商业计划书的8切记
2019/07/15 职场文书
《曾国藩家书》读后感——读家书,立家风
2019/08/21 职场文书
redis限流的实际应用
2021/04/24 Redis