侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python 基于Twisted框架的文件夹网络传输源码

Python  /  管理员 发布于 7年前   151

由于文件夹可能有多层目录,因此需要对其进行递归遍历。

本文采取了简单的协议定制,定义了五条命令,指令Head如下:
Sync:标识开始同步文件夹
End:标识结束同步
File:标识传输的文件名(相对路径)
Folder:标志文件夹(相对路径)
None:文件内容

每条命令以CMB_BEGIN开始,以CMB_END结束。

客户端需要对接收缓冲做解析,取出一条一条的指令,然后根据指令的Head做相应的处理,比如创建文件夹、写入文件等。

下面是服务端的代码:

from twisted.internet import reactorfrom twisted.internet.protocol import Protocol,Factoryfrom twisted.protocols.basic import LineReceiverimport osimport struct BUFSIZE = 4096 class SimpleLogger(Protocol):  def connectionMade(self):    print 'Got connection from', self.transport.client   def connectionLost(self, reason):    print self.transport.client, 'disconnected'   def dataReceived(self, line):    print line    self.transport.write("Hello Client, I am the Server!\r\n")     self.transport.write("CMB_BEGIN")    self.transport.write("Sync")    self.transport.write("CMB_END")    self.send_file_folder('server')   def send_file_folder(self,folder):    '''send folder to the client'''    for f in os.listdir(folder):      sourceF = os.path.join(folder, f)      if os.path.isfile(sourceF):  print 'File:',sourceF[7:]        self.transport.write("CMB_BEGIN")        self.transport.write("File:" + sourceF[7:])        self.transport.write("CMB_END")        fp = open(sourceF,'rb')        while 1:          filedata = fp.read(BUFSIZE)          if not filedata: break          else:self.transport.write("CMB_BEGIN")self.transport.write(filedata)print 'send size:::::::::',len(filedata)self.transport.write("CMB_END")        fp.close()        self.transport.write("CMB_BEGIN")        self.transport.write("End")        self.transport.write("CMB_END")      if os.path.isdir(sourceF):        print 'Folder:',sourceF[7:]        self.transport.write("CMB_BEGIN")        self.transport.write("Folder:" + sourceF[7:])        self.transport.write("CMB_END")        self.send_file_folder(sourceF) factory = Factory()factory.protocol = SimpleLoggerreactor.listenTCP(1234, factory)reactor.run()

Server在收到Client的某个信号之后(此代码中,当Client随便向Server发送任何内容都可),Server即会调用send_file_folder将sever文件夹下的内容全部发送给客户端。

服务端运行结果如下:

下面是客户端的代码:

from twisted.internet.selectreactor import SelectReactorfrom twisted.internet.protocol import Protocol,ClientFactoryfrom twisted.protocols.basic import LineReceiverimport osfrom struct import * reactor = SelectReactor()protocol = Protocol()prepare = 0filename = ""sourceDir = 'client'recvBuffer = '' def delete_file_folder(src):  '''delete files and folders'''  if os.path.isfile(src):    try:      os.remove(src)    except:      pass  elif os.path.isdir(src):    for item in os.listdir(src):      itemsrc = os.path.join(src,item)      delete_file_folder(itemsrc)     try:      os.rmdir(src)    except:      pass def clean_file_folder(src):  '''delete files and child folders'''  delete_file_folder(src)  os.mkdir(src) def writefile(filename,data):  print 'write file size:::::::::',len(data)  fp = open(filename,'a+b')  fp.write(data)  fp.close() class QuickDisconnectedProtocol(Protocol):  def connectionMade(self):    print "Connected to %s."%self.transport.getPeer().host    self.transport.write("Hello server, I am the client!\r\n")  def dataReceived(self, line):    global prepare    global filename    global sourceDir    global recvBuffer     recvBuffer = recvBuffer + line    self.processRecvBuffer()   def processRecvBuffer(self):    global prepare    global filename    global sourceDir    global recvBuffer     while len(recvBuffer) > 0 :      index1 = recvBuffer.find('CMB_BEGIN')      index2 = recvBuffer.find('CMB_END')       if index1 >= 0 and index2 >= 0:        line = recvBuffer[index1+9:index2]        recvBuffer = recvBuffer[index2+7:]         if line == 'Sync':          clean_file_folder(sourceDir)         if line[0:3] == "End":          prepare = 0        elif line[0:5] == "File:":          name = line[5:]          filename = os.path.join(sourceDir, name)          print 'mk file:',filename          prepare = 1        elif line[0:7] == "Folder:":          name = line[7:]          filename = os.path.join(sourceDir, name)          print 'mkdir:',filename          os.mkdir(filename)        elif prepare == 1:          writefile(filename,line)      else:        break  class BasicClientFactory(ClientFactory):  protocol=QuickDisconnectedProtocol  def clientConnectionLost(self,connector,reason):    print 'Lost connection: %s'%reason.getErrorMessage()    reactor.stop()  def clientConnectionFailed(self,connector,reason):    print 'Connection failed: %s'%reason.getErrorMessage()    reactor.stop() reactor.connectTCP('localhost',1234,BasicClientFactory())reactor.run()

客户端提取出来自Server的指令,当提取出Sync指令时,则将sourceDir目录清空,然后根据后续的指令,跟Server的文件夹进行同步。

客户端运行结果如下:

需要注意的地方:
Client写入文件时,需要以二进制的方式打开文件,否则,在传输二进制文件时可能出现错误或导致文件损坏。

经过测试,代码可以正常的运行,文件夹同步成功,文本文件、图像和其他类型的二进制文件均可正常传输。


  • 上一条:
    python3新特性函数注释Function Annotations用法分析
    下一条:
    python 网络编程常用代码段
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客