>  기사  >  백엔드 개발  >  Twisted 프레임워크 기반의 Python 폴더 네트워크 전송 소스 코드

Twisted 프레임워크 기반의 Python 폴더 네트워크 전송 소스 코드

高洛峰
高洛峰원래의
2017-02-03 16:15:331002검색

폴더에는 여러 수준의 디렉터리가 있을 수 있으므로 재귀적으로 탐색해야 합니다.

이 글에서는 간단한 프로토콜 사용자 정의를 사용하고 Head 명령 5개를 정의합니다.
Sync: 폴더의 동기화 시작을 나타냅니다.
End: 동기화의 끝을 나타냅니다.
파일: 전송할 파일을 식별합니다. 이름(상대 경로)
폴더: 플래그 폴더(상대 경로)
없음: 파일 내용

각 명령은 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()

클라이언트에서 추출한 내용은 다음과 같습니다. Sync 명령이 추출되면 sourceDir 디렉터리가 지워지고 후속 지침에 따라 Server 폴더와 동기화됩니다.

클라이언트 실행 결과는 다음과 같습니다.

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

주의사항:
클라이언트가 파일을 작성할 때 파일을 열어야 합니다. 바이너리 모드를 사용하지 않으면 바이너리 파일을 전송할 때 오류가 발생하거나 파일이 손상될 수 있습니다.

테스트 후 코드가 정상적으로 실행되고 폴더 동기화가 성공하며 텍스트 파일, 이미지 및 기타 유형의 바이너리 파일이 정상적으로 전송될 수 있습니다.

Twisted 프레임워크를 기반으로 한 더 많은 Python 폴더 네트워크 전송 소스 코드 기반 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.