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

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

