Heim > Artikel > Backend-Entwicklung > Quellcode für die Netzwerkübertragung von Python-Ordnern basierend auf dem Twisted-Framework
Da ein Ordner mehrere Verzeichnisebenen haben kann, muss er rekursiv durchlaufen werden.
Dieser Artikel verwendet eine einfache Protokollanpassung und definiert fünf Befehle. Der Befehlskopf lautet wie folgt:
Sync: identifiziert den Beginn der Synchronisierung des Ordners
Ende: identifiziert das Ende der Synchronisierung
Datei: identifiziert die zu übertragende Datei. Name (relativer Pfad)
Ordner: Flag-Ordner (relativer Pfad)
Keine: Dateiinhalt
Jeder Befehl beginnt mit CMB_BEGIN und endet mit CMB_END.
Der Client muss den Empfangspuffer analysieren, die Anweisungen einzeln herausnehmen und dann die entsprechende Verarbeitung entsprechend dem Kopf der Anweisung durchführen, z. B. das Erstellen von Ordnern, das Schreiben von Dateien usw.
Das Folgende ist der Servercode:
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()
Nachdem der Server ein Signal vom Client empfangen hat (in diesem Code kann der Client beliebige Inhalte an den Server senden), sendet der Server den_Dateiordner wird aufgerufen, um den gesamten Inhalt des Serverordners an den Client zu senden.
Die laufenden Ergebnisse des Servers lauten wie folgt:
Das Folgende ist der Code des Clients:
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()
Der Der Client extrahiert die Anweisungen vom Server. Wenn die Sync-Anweisung extrahiert wird, wird das Verzeichnis „sourceDir“ gelöscht und dann gemäß den nachfolgenden Anweisungen mit dem Serverordner synchronisiert.
Die Client-Ausführungsergebnisse sind wie folgt:
Wichtige Dinge:
Wenn der Client eine Datei schreibt, muss er die Datei öffnen Andernfalls kann es bei der Übertragung von Binärdateien zu Fehlern oder zur Beschädigung der Datei kommen.
Nach dem Test kann der Code normal ausgeführt werden, die Ordnersynchronisierung ist erfolgreich und Textdateien, Bilder und andere Arten von Binärdateien können normal übertragen werden.
Weitere Artikel, die auf dem Twisted-Framework basieren und auf Quellcode für die Netzwerkübertragung von Python-Ordnern basieren, finden Sie auf der chinesischen PHP-Website!