Twisted フレームワークに基づく Python フォルダー ネットワーク送信ソース コード

高洛峰
リリース: 2017-02-03 16:15:33
オリジナル
1001 人が閲覧しました

フォルダーには複数のレベルのディレクトリが含まれる場合があるため、再帰的にスキャンする必要があります。

この記事では、単純なプロトコルのカスタマイズを採用し、5 つのコマンドを定義します。 コマンドの先頭は次のとおりです:
Sync: 同期の開始フォルダーを識別します。
End: 同期の終了を識別します。
File: 送信のファイル名 (相対パス) を識別します。
フォルダー: ファイルフォルダー (相対パス) を識別します。
なし: ファイルの内容

各コマンドは CMB_BEGIN で始まり CMB_END で終わります。

クライアントは受信バッファを解析し、命令を一つずつ取り出し、命令の先頭に従ってフォルダーの作成やファイルの書き込みなどの対応する処理を実行する必要があります。

以下はサーバー コードです:

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()
ログイン後にコピー

サーバーがクライアントからシグナルを受信した後 (このコードでは、クライアントは任意のコンテンツをサーバーに送信できます)、サーバーは send_file_folder を呼び出してサーバー フォルダーのコンテンツを転送します。すべてクライアントに送信されます。

サーバーの実行結果は次のとおりです:

Twisted フレームワークに基づく Python フォルダー ネットワーク送信ソース コード

以下はクライアントのコードです:

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()
ログイン後にコピー

クライアントは、同期命令が抽出されると、sourceDir ディレクトリがクリアされます。をクリックし、その後の指示に従ってサーバーフォルダーと同期します。

クライアントの実行結果は次のとおりです:

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

注意事項:
クライアントがファイルを書き込むときは、ファイルをバイナリ モードで開く必要があります。そうしないと、バイナリ ファイルの転送時にエラーが発生したり、ファイルが破損する可能性があります。破損する。

テスト後、コードは正常に実行でき、フォルダーの同期は成功し、テキスト ファイル、画像、その他の種類のバイナリ ファイルを正常に転送できます。

Twisted フレームワークに基づくフォルダー ネットワーク送信ソース コードに関する Python 関連の記事については、PHP 中国語 Web サイトに注目してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート