【问题标题】:twisted not sending entire file with twisted client and server tcp transfer扭曲不使用扭曲的客户端和服务器 tcp 传输发送整个文件
【发布时间】:2012-06-29 19:30:08
【问题描述】:

编辑:由于我通过文本附加文件没有正确保存,我决定重写我最初希望的方式并将文件保存为流: 扭曲的服务器:

from twisted.internet import reactor, protocol
import os,json

class Echo(protocol.Protocol):
    f = file
    def dataReceived(self, data):
        try:
            try:
                print format(json.loads(data))
                print "got jason"
                self.f=open("test.png","wb")

                self.transport.write("ready")
            except:
                print "filedata incoming!"
                self.f.write(data)
        except:
            print "unknown error" #happens if we don't receive json first

    def connectionLost(self, reason):
        if self.f!=file:self.f.close()

def main():
    """This runs the protocol on port 8000"""
    factory = protocol.ServerFactory()
    factory.protocol = Echo
    reactor.listenTCP(8000,factory)
    reactor.run()

# this only runs if the module was *not* imported
if __name__ == '__main__':
    main()

下面是原帖

Twisted 发送了 99.9% 的文件,然后似乎就是这样,我想我写的文件不正确。

扭曲的服务器:

from twisted.internet import reactor, protocol
import os,json

class Echo(protocol.Protocol):

    def dataReceived(self, data):
        try:
            print format(json.loads(data))
            print "got jason"
            self.transport.write("ready")
        except:
            print "filedata incoming!"
            f = open("test.png","a")
            f.write(data)
            f.close()


def main():
    """This runs the protocol on port 8000"""
    factory = protocol.ServerFactory()
    factory.protocol = Echo
    reactor.listenTCP(8000,factory)
    reactor.run()

# this only runs if the module was *not* imported
if __name__ == '__main__':
    main()

扭曲的客户端:

from twisted.internet import reactor, protocol
import os,json

fname="pic.png"

class EchoClient(protocol.Protocol):
    """Once connected, send a message, then print the result."""

    def connectionMade(self):

        fsize = os.path.getsize(fname) 
        self.transport.write(json.dumps({"file":{"size":fsize}}))

    def sendFile(self):
        print "sending file" 
        f = open(fname,"rb")
        self.transport.write(f.read())
        f.close()
        print "closing conn"
        self.transport.loseConnection()

    def dataReceived(self, data):
        "As soon as any data is receive"
        print "Server said: ", data
        self.sendFile()


    def connectionLost(self, reason):
        print "connection lost"

class EchoFactory(protocol.ClientFactory):
    protocol = EchoClient

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed - goodbye!"
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        print "Connection lost - goodbye!"
        reactor.stop()


# this connects the protocol to a server runing on port 8000
def main():
    f = EchoFactory()
    reactor.connectTCP("localhost", 8000, f)
    reactor.run()

# this only runs if the module was *not* imported
if __name__ == '__main__':
    main()

基本上服务器正在运行并监听,客户端连接并立即发送json,服务器接收数据包并告诉发送客户端'ok',然后客户端发送文件;然后服务器接收文件并将其写入磁盘。我只是在测试,所以这个程序可能没有多大意义,尤其是文件附加的使用——但我注意到在传输和最终写入之后,文件的大小与原始文件的大小差不多,但不完全和小了大约 300 字节,因此几乎没用。 我是否错误地发送了文件?还是只是写错了?哦,是的,我正在同一台计算机上测试服务器和客户端。

最终,我计划向两台本地计算机发送和从两台本地计算机发送 1GB 的文件以进行备份,并希望将文件作为数据流写入,我不喜欢我正在使用的附加方法,但我不喜欢'不知道如何在不实际打开文件的情况下引用文件对象,这是我第一次收到 json 对象时才想做的事情。

谢谢!

【问题讨论】:

    标签: python tcp twisted file-transfer


    【解决方案1】:

    您正在打开“test.png”以添加文本。这是故意的吗?

    你还有一个简单的except,这是个坏主意,因为它会捕获所有异常。仅捕获您期望的那些异常。

    【讨论】:

    • 我想不出在第一个 json 消息之后打开文件的好方法,并且在发送文件数据的后续时间仍然正确引用文件,所以我选择了 append- - 我没有意识到这是用于文本的;我需要使用 r+b 和 seek 命令吗?我真的只想将内容流式传输到文件中并在之后关闭它,问题是流来自几个数据包,因此该函数被多次调用。我也意识到除了失败是开放的,一旦我正确保存了文件,我计划清理它。感谢您的意见!
    • 要以二进制模式追加,请使用“ab”。
    • 我现在可以正确写入文件了,谢谢 :) 现在找到一种更有效的方法来执行此操作,而不是附加文件。
    【解决方案2】:

    问题是您希望dataReceived 立即收到您的所有数据。互联网不是这样运作的:see this Twisted FAQ for an explanation of why this is so and how to fix your code

    【讨论】:

    • 我完全不希望会发生这种情况,我希望该函数会运行多次
    • 您的dataReceived 不正确,这就是我要告诉您的。它有时会失败。你不能期望每次调用它都是一个完整的 JSON 对象。
    • 很好,我必须建立一个更好的系统来处理碎片化的 json 对象,我还没有经历过,因为我的 json 对象太小了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    相关资源
    最近更新 更多