AttributeError:当使用pickle over socket时,'module'对象没有属性''

时间:2012-03-25 21:20:59

标签: python pickle

我正在尝试使用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

1 个答案:

答案 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:])

请记住,这将阻止,直到可以发送所有字节。如果您不想这样,则必须将其集成到选择循环中。

打印数据的哈希可能是一个有用的测试,可以确定错误是在传输数据还是在酸洗/去除数据中。