Python 基於Twisted框架的資料夾網路傳輸原始碼
由於資料夾可能有多層目錄,因此需要對其進行遞迴遍歷。
本文采取了簡單的協議定製,定義了五條命令,指令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寫入檔案時,需要以二進位制的方式開啟檔案,否則,在傳輸二進位制檔案時可能出現錯誤或導致檔案損壞。
經過測試,程式碼可以正常的執行,資料夾同步成功,文字檔案、影像和其他型別的二進位制檔案均可正常傳輸。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2680954/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 直播app原始碼中的資料是如何在網路中傳輸的?APP原始碼
- 網路協議之:基於UDP的高速資料傳輸協議UDT協議UDP
- Python 基於 TCP 傳輸協議的網路通訊實現PythonTCP協議
- Python 網路資料傳輸協議 TCP 程式設計Python協議TCP程式設計
- netty系列之:基於流的資料傳輸Netty
- 資料線線損和長度對資料傳輸和網路傳輸的影響
- 關於廣域網的資料傳輸問題
- 網路遊戲資料傳輸:粘包的處理遊戲
- 使用EXPDP IMPDP傳輸不同資料庫的不同表空間(新增網路傳輸)資料庫
- 網路中的資料傳輸模式有哪些-鐳速模式
- 基於分發與計算的GRTN全球實時傳輸網路
- Oracle 12C 跨網路傳輸資料庫Oracle資料庫
- 關於印度跨境資料傳輸,印度放寬了跨境資料傳輸
- Andriod 網路框架 OkHttp 原始碼解析框架HTTP原始碼
- TransData for Mac - 網路資料傳輸速率監測軟體Mac
- 網路資料傳輸速率監測軟體:TransData for MacMac
- 技術筆記(12)網路資料傳輸問題筆記
- mongodb核心transport_layer網路傳輸層模組原始碼實現三MongoDB原始碼
- mongodb核心transport_layer 網路傳輸層模組原始碼實現四MongoDB原始碼
- 如何用C++封裝一個簡單的資料流操作類(附原始碼),從而用於網路上的資料傳輸和解析?C++封裝原始碼
- 不安全網路中的資料安全傳輸利器——GnuPG(上)
- 微夢森網路-基於3.1.2框架框架
- Android 網路框架 Retrofit 原始碼解析Android框架原始碼
- 阿里雲CDN不止於加速:基於https**演算法構建安全資料傳輸鏈路阿里HTTP演算法
- 網路傳輸協議協議
- 網路中的圖片傳輸
- socket網路傳輸的問題
- 網路資料原來是這麼傳輸的(結合動畫解析)動畫
- Socket開發框架之資料傳輸協議框架協議
- 基於VITA57.1標準的8路SFP+光纖通道資料傳輸FMC子卡模組
- 資料檔案在網路“裸奔”,如何在網際網路中進行檔案傳輸?
- 網路資料傳輸時作業系統幹了什麼?作業系統
- 國際網路專線能否保障企業資料的全球快速傳輸?
- 資料夾怎麼拖到微信 微信傳送資料夾的辦法
- 路由器網路中資料包傳輸分析路由器
- 網路元件 基於Retrofit2+RxJava2+GSON/Fastjson的網路框架元件RxJavaASTJSON框架
- 網路資料分析:原始大資料大資料
- 基於python的大資料分析-資料處理(程式碼實戰)Python大資料