2012-04-12 8 views
0

Ich muss ein Array von Nameduples von einem Socket senden.Pack Array von namedtuples in PYTHON

Um das Array von namedtuples I de folgenden verwenden zu erstellen:

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

Jetzt ist das gefüllt, ich brauche "listaPeers [200]"

, wie ich es tun kann, packen?

So etwas wie ?:

packedData = struct.pack('XXXX',listaPeers) 
+0

Wie Sie auch andere Tupel tun. – Marcin

+0

Danke. Sie wollen jedes namedtuple einzeln verpacken und eins nach dem anderen schicken? – saimonx

+0

Sie können sie separat packen und die Ergebnisse verketten. – alexis

Antwort

1

allererst Sie falsch verwenden namedtuple. Es sollte in etwa so aussehen:

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

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

Wie für die Verpackung hängt es ab, was Sie am anderen Ende verwenden möchten. Wenn die Daten von Python gelesen werden, können Sie einfach das Modul Pickle verwenden.

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

Sie können ganze Reihe von ihnen auf einmal einlegen.

0

Es ist nicht so einfach - Ja, für ganze Zahlen und einfache Zahlen ist es möglich, direkt von benannten Tupeln zu Daten zu packen, die vom struct-Paket bereitgestellt werden.

Allerdings halten Sie Ihre Daten als Zeichenfolgen, nicht als Zahlen - es ist eine einfache Sache, im Fall des Ports in int zu konvertieren - wie es eine einfache ganze Zahl ist, erfordert aber etwas Jonglieren, wenn es darum geht 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) 
         ) 

Und Sie verwenden dann die "Pack" -Funktion von hier, um Ihre Struktur zu packen, wie Sie scheinen wollen.

Aber zuerst, versuchen Sie die Tatsache, dass Sie Ihre "listaPiers" falsch erstellen (Ihr Beispielcode wird einfach mit einem IndexError fehlschlagen) - verwenden Sie eine leere Liste und die Append-Methode, um neue benannte Tupel mit IP einzufügen/Port-Paare, wie jedes Element:

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) 
0

ISTR dass Beize in Serverprozessen unsicher betrachtet wird, wenn die Server-Prozessdaten von nicht vertrauenswürdigen Clients gebeizt empfangen.

Sie möchten vielleicht eine Art Trennzeichen für die Datensätze und Felder (vielleicht \ 0 und \ 001 oder \ 376 und \ 377) erstellen. Dann wird eine Nachricht wie eine Textdatei in Datensätze und Felder aufgeteilt, die durch Leerzeichen und Zeilenumbrüche getrennt sind. Oder Sie können Leerzeichen und Zeilenumbrüche verwenden, wenn Ihre normalen Daten diese nicht enthalten.

ich dieses Modul sehr wertvoll für die Gestaltung Daten in socket-basierten Protokollen finden: http://stromberg.dnsalias.org/~strombrg/bufsock.html Es läßt Dich Dinge wie „bis zur nächsten Null-Byte lesen,“ tun oder „die nächsten 10 Zeichen lesen“ - ohne Sorge zu müssen über die Komplexität von IP-Aggregation oder Aufspaltung von Paketen.