폴더에는 여러 수준의 디렉터리가 있을 수 있으므로 재귀적으로 탐색해야 합니다.
이 글에서는 간단한 프로토콜 사용자 정의를 사용하고 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를 호출하여 클라이언트의 모든 콘텐츠를 보냅니다. 클라이언트에 서버 폴더를 보냅니다.
서버의 실행 결과는 다음과 같습니다.
다음은 클라이언트의 코드입니다.
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 폴더와 동기화됩니다.
클라이언트 실행 결과는 다음과 같습니다.
주의사항:
클라이언트가 파일을 작성할 때 파일을 열어야 합니다. 바이너리 모드를 사용하지 않으면 바이너리 파일을 전송할 때 오류가 발생하거나 파일이 손상될 수 있습니다.
테스트 후 코드가 정상적으로 실행되고 폴더 동기화가 성공하며 텍스트 파일, 이미지 및 기타 유형의 바이너리 파일이 정상적으로 전송될 수 있습니다.
Twisted 프레임워크를 기반으로 한 더 많은 Python 폴더 네트워크 전송 소스 코드 기반 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!