0

我需要通过套接字发送一个命名元组数组。

要创建命名元组数组,我使用以下内容:

listaPeers=[]
for i in range(200):
     ipPuerto=collections.namedtuple('ipPuerto', 'ip, puerto')
     ipPuerto.ip="121.231.334.22"
     ipPuerto.puerto="8988"
     listaPeers.append(ipPuerto)

现在已经填满了,我需要打包“listaPeers[200]”

我该怎么做?

就像是?:

packedData = struct.pack('XXXX',listaPeers)
4

3 回答 3

1

首先,您错误地使用了namedtuple。它应该看起来像这样:

 # ipPuerto is a type
 ipPuerto=collections.namedtuple('ipPuerto', 'ip, puerto')

 # theTuple is a tuple object
 theTuple = ipPuerto("121.231.334.22", "8988")

至于包装,这取决于你想在另一端使用什么。如果数据将由 Python 读取,则可以使用 Pickle 模块。

import cPickle as Pickle
pickledTuple = Pickle.dumps(theTuple)

您可以一次腌制整个数组。

于 2012-04-12T17:39:45.713 回答
0

它不是那么简单 - 是的,对于整数和简单数字,可以直接从命名元组打包到 struct 包提供的数据。

但是,您将数据保存为字符串,而不是数字 - 在端口的情况下转换为 int 是一件简单的事情 - 因为它是一个简单的整数,但在涉及 IP 时需要一些杂耍。

def ipv4_from_str(ip_str):
    parts = ip_str.split(".")
    result = 0
    for part in parts:
        result <<= 8
        result += int(part)
    return result

def ip_puerto_gen(list_of_ips):
    for ip_puerto in list_of_ips:
        yield(ipv4_from_str(ip_puerto.ip))
        yield(int(ip_puerto.puerto))


def pack(list_of_ips):
    return struct.pack(">" + "II" * len(list_of_ips),
                       *ip_puerto_gen(list_of_ips)
                       )

然后,您可以使用此处的“打包”功能来打包您似乎想要的结构。

但首先,尝试您错误地创建“listaPiers”这一事实(您的示例代码将因 IndexError 而失败) - 使用空列表,并在其上使用 append 方法插入具有 ip/port 对的新命名元组作为每个元素:

listaPiers = []
ipPuerto=collections.namedtuple('ipPuerto', 'ip, puerto')
for x in range(200):
   new_element = ipPuerto("123.123.123.123", "8192")
   listaPiers.append(new_element)

data = pack(listaPiers)
于 2012-04-12T17:42:50.250 回答
0

如果服务器进程从不受信任的客户端接收腌制数据,则 ISTR 认为腌制在服务器进程中是不安全的。

您可能想为记录和字段(可能是 \0 和 \001 或 \376 和 \377)提供某种分隔符。然后将消息放在一起有点像一个文本文件,它被分成由空格和换行符分隔的记录和字段。或者就此而言,如果您的正常数据不包括这些,您可以使用空格和换行符。

我发现这个模块对于在基于套接字的协议中构建数据非常有价值: http: //stromberg.dnsalias.org/~strombrg/bufsock.html 它可以让您执行诸如“读取直到下一个空字节”或“读取接下来 10 个字符”——无需担心 IP 聚合或拆分数据包的复杂性。

于 2012-04-12T18:08:23.420 回答