我正在尝试使用pickle来编码类的实例并将其发送到套接字并在另一端对其进行解码,但是在调用pickle.loads()时,在到达另一端AttributeError: 'module' object has no attribute ''
时会抛出它。谷歌搜索后我确认pickle正确导入包含类定义的模块。我无法弄清楚为什么它正在寻找没有名称的属性
接收数据包的功能
def run(self):
while self.alive.isSet():
try:
cmd = self.cmd_q.get(True, 0.1)
self.log.debug('Q Returned')
self.handlers[cmd.type](cmd)
except Queue.Empty as e:
#self.log.debug('Q Returned Empty')
pass
if self.connected.isSet():
self.log.debug('checking packets')
if self.conn:
x = select.select((self.conn,),(),(), 0.1)
self.log.debug('SERVER returned')
else:
x = select.select((self.sock,),(),(), 0.1)
self.log.debug('CLIENT returned')
if len(x[0]) != 0:
self.log.debug('Got Packet')
packet = x[0][0].makefile('rwb').readline()
self.__reply_receive(packet)
发送功能
def __handle_send(self, cmd):
self.log.debug('Sending.....')
if self.connected.isSet():
packet = pickle.dumps(cmd.data,pickle.HIGHEST_PROTOCOL)
if self.conn:
self.conn.send(packet + '\n')
else:
self.sock.send(packet + '\n')
self.log.debug('Sent!')
和类定义
class Packet(object):
"""
LINEUP (line)
UPDATE (dict)
INPUT (line)
DISCONN None
TEST (line)
"""
LINEUP, UPDATE, INPUT, DISCONN, TEST = range(5)
def __init__(self, type, data = 'blarg'):
self.type = type
self.data = data
答案 0 :(得分:1)
我认为你不能依赖pickle.dumps的结果来包含任何换行符。您需要另一种方法来找出腌制对象的结束位置。你可以先发送长度来做到这一点。 (pickle.load可以确定对象的结束位置,但是必须阻塞才能读取整个对象。)
您对socket.send方法的使用不正确。它可以发送比您请求的更少的字节,它将返回发送的字节数。你需要创建一个循环来发送剩余的字节,如下所示:
def send_all(sock, string):
bytes_sent = 0
while bytes_sent < len(string):
bytes_sent += sock.send(string[bytes_sent:])
请记住,这将阻止,直到可以发送所有字节。如果您不想这样,则必须将其集成到选择循环中。
打印数据的哈希可能是一个有用的测试,可以确定错误是在传输数据还是在酸洗/去除数据中。