Heim  >  Artikel  >  Backend-Entwicklung  >  Quellcode für die Netzwerkübertragung von Python-Ordnern basierend auf dem Twisted-Framework

Quellcode für die Netzwerkübertragung von Python-Ordnern basierend auf dem Twisted-Framework

高洛峰
高洛峰Original
2017-02-03 16:15:33991Durchsuche

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:

Quellcode für die Netzwerkübertragung von Python-Ordnern basierend auf dem Twisted-Framework

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:

Python 基于Twisted框架的文件夹网络传输源码

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn