Maison >développement back-end >Tutoriel Python >Code source de transmission réseau du dossier Python basé sur le framework Twisted

Code source de transmission réseau du dossier Python basé sur le framework Twisted

高洛峰
高洛峰original
2017-02-03 16:15:331008parcourir

Étant donné qu'un dossier peut avoir plusieurs niveaux de répertoires, il doit être parcouru de manière récursive.

Cet article utilise une personnalisation simple du protocole et définit cinq commandes. La commande Head est la suivante :
Sync : identifie le début de la synchronisation du dossier
Fin : identifie la fin de la synchronisation
Fichier : identifie le fichier à transférer Nom (chemin relatif)
Dossier : Dossier indicateur (chemin relatif)
Aucun : Contenu du fichier

Chaque commande commence par CMB_BEGIN et se termine par CMB_END.

Le client doit analyser le tampon de réception, retirer les instructions une par une, puis effectuer le traitement correspondant selon le responsable de l'instruction, comme la création de dossiers, l'écriture de fichiers, etc.

Voici le code du serveur :

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()

Après que le serveur ait reçu un signal du client (dans ce code, le client peut envoyer n'importe quel contenu au serveur), le serveur Send_file_folder sera appelé pour envoyer tout le contenu du dossier serveur au client.

Les résultats d'exécution du serveur sont les suivants :

Code source de transmission réseau du dossier Python basé sur le framework Twisted

Voici le code du client :

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()

Le Le client extrait les instructions du serveur, lorsque l'instruction Sync est extraite, le répertoire sourceDir est effacé, puis synchronisé avec le dossier Serveur selon les instructions ultérieures.

Les résultats d'exécution du client sont les suivants :

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

Choses à noter :
Lorsque le client écrit un fichier, il doit l'ouvrir dans mode binaire, sinon des erreurs peuvent survenir lors du transfert de fichiers binaires ou provoquer une corruption de fichiers.

Après les tests, le code peut s'exécuter normalement, la synchronisation des dossiers est réussie et les fichiers texte, images et autres types de fichiers binaires peuvent être transférés normalement.

Pour plus d'articles liés au code source de transmission réseau de dossiers Python basé sur le framework Twisted, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn