首页 后端开发 Python教程 Python 基于Twisted框架的文件夹网络传输源码

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

Feb 03, 2017 pm 04:15 PM

由于文件夹可能有多层目录,因此需要对其进行递归遍历。

本文采取了简单的协议定制,定义了五条命令,指令Head如下:
Sync:标识开始同步文件夹
End:标识结束同步
File:标识传输的文件名(相对路径)
Folder:标志文件夹(相对路径)
None:文件内容

每条命令以CMB_BEGIN开始,以CMB_END结束。

客户端需要对接收缓冲做解析,取出一条一条的指令,然后根据指令的Head做相应的处理,比如创建文件夹、写入文件等。

下面是服务端的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

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

登录后复制

Server在收到Client的某个信号之后(此代码中,当Client随便向Server发送任何内容都可),Server即会调用send_file_folder将sever文件夹下的内容全部发送给客户端。

服务端运行结果如下:

24.jpg

下面是客户端的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

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

登录后复制

客户端提取出来自Server的指令,当提取出Sync指令时,则将sourceDir目录清空,然后根据后续的指令,跟Server的文件夹进行同步。

客户端运行结果如下:

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

需要注意的地方:
Client写入文件时,需要以二进制的方式打开文件,否则,在传输二进制文件时可能出现错误或导致文件损坏。

经过测试,代码可以正常的运行,文件夹同步成功,文本文件、图像和其他类型的二进制文件均可正常传输。

更多Python 基于Twisted框架的文件夹网络传输源码相关文章请关注PHP中文网!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章标签

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

我如何使用美丽的汤来解析HTML? 我如何使用美丽的汤来解析HTML? Mar 10, 2025 pm 06:54 PM

我如何使用美丽的汤来解析HTML?

如何在Python中下载文件 如何在Python中下载文件 Mar 01, 2025 am 10:03 AM

如何在Python中下载文件

python中的图像过滤 python中的图像过滤 Mar 03, 2025 am 09:44 AM

python中的图像过滤

如何使用Python查找文本文件的ZIPF分布 如何使用Python查找文本文件的ZIPF分布 Mar 05, 2025 am 09:58 AM

如何使用Python查找文本文件的ZIPF分布

如何使用Python使用PDF文档 如何使用Python使用PDF文档 Mar 02, 2025 am 09:54 AM

如何使用Python使用PDF文档

如何在django应用程序中使用redis缓存 如何在django应用程序中使用redis缓存 Mar 02, 2025 am 10:10 AM

如何在django应用程序中使用redis缓存

如何使用TensorFlow或Pytorch进行深度学习? 如何使用TensorFlow或Pytorch进行深度学习? Mar 10, 2025 pm 06:52 PM

如何使用TensorFlow或Pytorch进行深度学习?

引入自然语言工具包(NLTK) 引入自然语言工具包(NLTK) Mar 01, 2025 am 10:05 AM

引入自然语言工具包(NLTK)

See all articles