6

私がやろうとしていることはかなり単純です: クライアントからサーバーにファイルを送信します。まず、クライアントはファイルに関する情報 (ファイルのサイズ) を送信します。次に、実際のファイルを送信します。

これは私がこれまでに行ったことです:

サーバー.py

from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver

import pickle
import sys

class Echo(LineReceiver):

    def connectionMade(self):
        self.factory.clients.append(self)
        self.setRawMode()

    def connectionLost(self, reason):
        self.factory.clients.remove(self)

    def lineReceived(self, data):
        print "line", data

    def rawDataReceived(self, data):
            try:
                obj = pickle.loads(data)
                print obj
            except:
                print data

        #self.transport.write("wa2")

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

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

Client.py

import pickle

from twisted.internet import reactor, protocol
import time
import os.path
from twisted.protocols.basic import LineReceiver

class EchoClient(LineReceiver):

    def connectionMade(self):
        file = "some file that is a couple of megs"
        filesize = os.path.getsize(file)
        self.sendLine(pickle.dumps({"size":filesize}))

        f = open(file, "rb")
        contents = f.read()
        print contents[:20]
        self.sendLine(contents[:20])
        f.close()

#        self.sendLine("hej")
#        self.sendLine("wa")

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

サーバーは、デシリアライズされたオブジェクトのみを出力します。

{'サイズ': 183574528L}

どうして?送信したいファイルの 20 文字はどうなりましたか?

代わりに「hej」と「wa」の送信を使用すると、両方を (2 回ではなく、同じメッセージで) 受信します。

誰か?

4

1 に答える 1

9

サーバーを setRawMode() で raw モードに設定したので、コールバック rawDataReceived が着信データ (lineReceived ではなく) で呼び出されます。rawDataReceived で受信したデータを出力すると、ファイルの内容を含むすべてが表示されますが、pickle を呼び出してデータをデシリアライズすると、無視されます。

データをサーバーに送信する方法を変更するか (netstring 形式をお勧めします)、コンテンツを pickle シリアル化オブジェクト内に渡し、これを 1 回の呼び出しで行います。

self.sendLine(pickle.dumps({"size":filesize, 'content': contents[:20]}))
于 2009-08-04T17:46:56.187 に答える