unpack需要长度为43的字符串参数 - Python

时间:2014-10-01 16:31:06

标签: python sockets udp

我有以下函数,从UDP套接字读取,并追加到字符串data

DATA_SIZE = 2048 
def handle_read(self):
        """
        This handles the incoming ntp response
        """
        try:
            data = ""
            while 1:
                current_data, _ = self.recvfrom(self.DATA_SIZE)
                self.log.info("msg: %s" % current_data)
                (header, length, typeID, param1, param2,
                param3, param4, name_string, checksum, footer,
                ) = struct.unpack("!2B I 4H 24s I B", current_data)
                print  (header, length, typeID, param1, param2,
                param3, param4, name_string, checksum, footer,
                )
                if not current_data:
                    break
                data += current_data
            self.log.info(data)
            # parse with the pysnmp into a summary
        except Exception, e:
            self.log.exception("The following exception happened: %s" % e)
        finally:
            self.handle_close()

当我执行代码时,我得到了:

  File "hello.py", line 67, in handle_read
    ) = struct.unpack("!2B I 4H 24s I B", current_data)
error: unpack requires a string argument of length 43

我试图调整字符串参数大小,但是出现了相同的错误。该函数基本上要做的是从self.recvfrom()读取并附加到data。有人可以帮忙吗? self.recvfrom()的结构如下:

0xpublic?kC0^0+>Linux manager 3.4.30 #1 SMP Wed Sep 3 11:31:42 UTC 2014 x86_64+C?R?
('1.2.3.4', 161)

这是我从服务器返回的SNMP消息,以及我正在与之通信的服务器IP。我们的想法是将SNMP MIB附加到该字符串中。

1 个答案:

答案 0 :(得分:0)

您的代码正在读取长度最多为2048字节的数据报,然后解码前43个字节以记录smtp信息。问题是数据报可能多于或少于43个字节。我认为您可以通过使用unpack_from解码消息的第一部分来解决您的问题,并简单地拒绝过小的消息。预编译结构节省了一点时间,所以我也这样做。

class Whatever(object):

    DATA_SIZE = 2048
    snmp_header = struct.Struct("!2B I 4H 24s I B")

    def handle_read(self):
            """
            This handles the incoming snmp response
            """
            try:
                data = ""
                while 1:
                    current_data, _ = self.recvfrom(self.DATA_SIZE)
                    self.log.info("msg: %s" % current_data)
                    if len(current_data) >= self.snmp_header.size:
                        (header, length, typeID, param1, param2,
                        param3, param4, name_string, checksum, footer,
                        ) = self.snmp_header.unpack_from("!2B I 4H 24s I B", current_data)
                        print  (header, length, typeID, param1, param2,
                        param3, param4, name_string, checksum, footer,
                        )
                    else:
                        print("received datagram too small")
                    if not current_data:
                        break
                    data += current_data
                self.log.info(data)
                # parse with the pysnmp into a summary
            except Exception, e:
                self.log.exception("The following exception happened: %s" % e)
            finally:
                self.handle_close()