由于文件夹可能有多层目录,因此需要对其进行递归遍历。
本文采取了简单的协议定制,定义了五条命令,指令Head如下:
Sync:标识开始同步文件夹
End:标识结束同步
File:标识传输的文件名(相对路径)
Folder:标志文件夹(相对路径)
None:文件内容
每条命令以CMB_BEGIN开始,以CMB_END结束。
客户端需要对接收缓冲做解析,取出一条一条的指令,然后根据指令的Head做相应的处理,比如创建文件夹、写入文件等。
下面是服务端的代码:
from twisted.internet import reactor from twisted.internet.protocol import Protocol,Factory from twisted.protocols.basic import LineReceiver import os import 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 = SimpleLogger reactor.listenTCP(1234, factory) reactor.run()
Server在收到Client的某个信号之后(此代码中,当Client随便向Server发送任何内容都可),Server即会调用send_file_folder将sever文件夹下的内容全部发送给客户端。
服务端运行结果如下:
下面是客户端的代码:
from twisted.internet.selectreactor import SelectReactor from twisted.internet.protocol import Protocol,ClientFactory from twisted.protocols.basic import LineReceiver import os from struct import * reactor = SelectReactor() protocol = Protocol() prepare = 0 filename = "" 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写入文件时,需要以二进制的方式打开文件,否则,在传输二进制文件时可能出现错误或导致文件损坏。
经过测试,代码可以正常的运行,文件夹同步成功,文本文件、图像和其他类型的二进制文件均可正常传输。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
暂无“Python 基于Twisted框架的文件夹网络传输源码”评论...
更新动态
2024年11月25日
2024年11月25日
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]