Python 基于Twisted框架的文件夾網(wǎng)絡(luò)傳輸源碼
由于文件夾可能有多層目錄,因此需要對(duì)其進(jìn)行遞歸遍歷。
本文采取了簡(jiǎn)單的協(xié)議定制,定義了五條命令,指令Head如下:
Sync:標(biāo)識(shí)開始同步文件夾
End:標(biāo)識(shí)結(jié)束同步
File:標(biāo)識(shí)傳輸?shù)奈募ㄏ鄬?duì)路徑)
Folder:標(biāo)志文件夾(相對(duì)路徑)
None:文件內(nèi)容
每條命令以CMB_BEGIN開始,以CMB_END結(jié)束。
客戶端需要對(duì)接收緩沖做解析,取出一條一條的指令,然后根據(jù)指令的Head做相應(yīng)的處理,比如創(chuàng)建文件夾、寫入文件等。
下面是服務(wù)端的代碼:
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的某個(gè)信號(hào)之后(此代碼中,當(dāng)Client隨便向Server發(fā)送任何內(nèi)容都可),Server即會(huì)調(diào)用send_file_folder將sever文件夾下的內(nèi)容全部發(fā)送給客戶端。
服務(wù)端運(yùn)行結(jié)果如下:

下面是客戶端的代碼:
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()
客戶端提取出來(lái)自Server的指令,當(dāng)提取出Sync指令時(shí),則將sourceDir目錄清空,然后根據(jù)后續(xù)的指令,跟Server的文件夾進(jìn)行同步。
客戶端運(yùn)行結(jié)果如下:

需要注意的地方:
Client寫入文件時(shí),需要以二進(jìn)制的方式打開文件,否則,在傳輸二進(jìn)制文件時(shí)可能出現(xiàn)錯(cuò)誤或?qū)е挛募p壞。
經(jīng)過(guò)測(cè)試,代碼可以正常的運(yùn)行,文件夾同步成功,文本文件、圖像和其他類型的二進(jìn)制文件均可正常傳輸。
- python如何通過(guò)twisted搭建socket服務(wù)
- Python3.6中Twisted模塊安裝的問(wèn)題與解決
- python安裝twisted的問(wèn)題解析
- python如何通過(guò)twisted實(shí)現(xiàn)數(shù)據(jù)庫(kù)異步插入
- python基于twisted框架編寫簡(jiǎn)單聊天室
- python 編程之twisted詳解及簡(jiǎn)單實(shí)例
- 剖析Python的Twisted框架的核心特性
- 實(shí)例解析Python的Twisted框架中Deferred對(duì)象的用法
- 詳解Python的Twisted框架中reactor事件管理器的用法
- 使用Python的Twisted框架編寫非阻塞程序的代碼示例
- Python的Twisted框架中使用Deferred對(duì)象來(lái)管理回調(diào)函數(shù)
- 使用Python的Twisted框架構(gòu)建非阻塞下載程序的實(shí)例教程
- Python的Twisted框架上手前所必須了解的異步編程思想
- 使用Python的Treq on Twisted來(lái)進(jìn)行HTTP壓力測(cè)試
- 利用Python的Twisted框架實(shí)現(xiàn)webshell密碼掃描器的教程
- 使用Python的Twisted框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的服務(wù)器
- 使用Python的Twisted框架編寫簡(jiǎn)單的網(wǎng)絡(luò)客戶端
- python開發(fā)實(shí)例之Python的Twisted框架中Deferred對(duì)象的詳細(xì)用法與實(shí)例
相關(guān)文章
Pycharm運(yùn)行加載文本出現(xiàn)錯(cuò)誤的解決方法
今天小編就為大家分享一篇Pycharm運(yùn)行加載文本出現(xiàn)錯(cuò)誤的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
通過(guò)Python腳本+Jenkins實(shí)現(xiàn)項(xiàng)目重啟
Jenkins是一個(gè)流行的開源自動(dòng)化服務(wù)器,用于快速構(gòu)建、測(cè)試和部署軟件,本文主要介紹了通過(guò)Python腳本+Jenkins實(shí)現(xiàn)項(xiàng)目重啟,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10
python接口自動(dòng)化使用requests庫(kù)發(fā)送http請(qǐng)求
這篇文章主要介紹了python接口自動(dòng)化使用requests庫(kù)發(fā)送http請(qǐng)求,HTTP協(xié)議?,一個(gè)基于TCP/IP通信協(xié)議來(lái)傳遞數(shù)據(jù),包括html文件、圖像、結(jié)果等,即是一個(gè)客戶端和服務(wù)器端請(qǐng)求和應(yīng)答的標(biāo)準(zhǔn)2022-08-08
Python實(shí)現(xiàn)亂序文件重新命名編號(hào)
這篇文章主要為大家詳細(xì)介紹一下Python的一個(gè)神操作,那就是實(shí)現(xiàn)亂序文件重新命名編號(hào)功能,文中的示例代碼講解詳細(xì),感興趣的可以嘗試一下2022-08-08
Python實(shí)現(xiàn)制作銷售數(shù)據(jù)可視化看板詳解
在數(shù)據(jù)時(shí)代,銷售數(shù)據(jù)分析的重要性已無(wú)需贅言。只有對(duì)銷售數(shù)據(jù)的準(zhǔn)確分析我們才有可能找準(zhǔn)數(shù)據(jù)變動(dòng)的原因。本文將介紹用Python制作銷售數(shù)據(jù)大屏的方法。感興趣的可以關(guān)注一下2021-11-11
Python+PyQT5實(shí)現(xiàn)手繪圖片生成器
這篇文章主要介紹了利用Python PyQT5制作一個(gè)手繪圖片生成器,可以將導(dǎo)入的彩色圖片通過(guò)python分析光源、灰度等操作生成手繪圖片。感興趣的可以跟隨小編一起了解一下2022-02-02
Python編程基礎(chǔ)之構(gòu)造方法和析構(gòu)方法詳解
這篇文章主要為大家詳細(xì)介紹了Python的構(gòu)造方法和析構(gòu)方法,使用Python編程基礎(chǔ),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Python面向?qū)ο缶幊剃P(guān)鍵深度探索類與對(duì)象
這篇文章主要為大家介紹了Python面向?qū)ο缶幊剃P(guān)鍵深度探索類與對(duì)象示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05

