我想做的很简单:从客户端向服务器发送一个文件。首先,客户端发送有关文件的信息——即文件的大小。然后它发送实际文件。
这是我到目前为止所做的:
服务器.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()
客户端.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”发送,我会同时收到它们(在同一条消息中,而不是两次)。
有人吗?
最佳答案
您已经使用 setRawMode() 将您的服务器设置为原始模式,因此回调 rawDataReceived 将使用传入数据(而不是 lineReceived)被调用。如果您打印在 rawDataReceived 中收到的数据,您会看到包括文件内容在内的所有内容,但是当您调用 pickle 反序列化数据时,它会被忽略。
要么更改向服务器发送数据的方式(我建议使用 netstring 格式),要么将内容传递到 pickle 序列化对象中,并在一次调用中执行此操作。
self.sendLine(pickle.dumps({"size":filesize, 'content': contents[:20]}))
关于python - Twisted python 的问题 - 发送二进制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1228722/