UDP-Client und -Server mit Twisted Python

Ich möchte einen Server und einen Client erstellen, die mit Twisted UDP-Pakete vom Netzwerk senden und empfangen. Ich habe dies bereits mit Sockets in Python geschrieben, möchte aber die Callback- und Threading-Funktionen von Twisted nutzen. Allerdings brauche ich Hilfe beim Design von Twisted.

Ich habe mehrere Arten von Paketen, die ich empfangen möchte, aber tun wir so, als gäbe es nur einen:

class Packet(object):
    def __init__(self, data=None):
        self.packet_type = 1
        self.payload = ''
        self.structure = '!H6s'
        if data == None:
            return

        self.packet_type, self.payload = struct.unpack(self.structure, data)

    def pack(self):
        return struct.pack(self.structure, self.packet_type, self.payload)

    def __str__(self):
        return "Type: {0}\nPayload {1}\n\n".format(self.packet_type, self.payload)

Ich habe eine Protokollklasse erstellt (fast direkte Kopie der Beispiele), die zu funktionieren scheint, wenn ich Daten von einem anderen Programm sende:

class MyProtocol(DatagramProtocol):
    def datagramReceived(self, data, (host, port)):
        p = Packet(data)
        print p

reactor.listenUDP(3000, MyProtocol())
reactor.run()

Was ich nicht weiß, ist, wie ich einen Client erstelle, der beliebige Pakete im Netzwerk senden kann, die vom Reaktor abgeholt werden:

# Something like this:
s = Sender()
p = Packet()
p.packet_type = 3
s.send(p.pack())
p.packet_type = 99
s.send(p.pack())

Ich muss auch sicherstellen, dass das Flag für die Wiederverwendung von Adressen auf dem Client und den Servern gesetzt ist, damit ich mehrere Instanzen gleichzeitig auf demselben Gerät ausführen kann (z. B. ein Skript sendet Heartbeats, ein anderes antwortet auf Heartbeats usw.).

Kann mir jemand zeigen, wie das mit Twisted gemacht werden kann?

Aktualisiere:

So mache ich das mit Sockets in Python. Ich kann mehrere Listener und Sender gleichzeitig ausführen und sie hören sich alle. Wie komme ich mit Twisted zu diesem Ergebnis? (Der zuhörende Teil muss kein separater Prozess sein.)

class Listener(Process):
    def __init__(self, ip='127.0.0.1', port=3000):
        Process.__init__(self)
        self.ip = ip
        self.port = port

    def run(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind((self.ip, self.port))

        data, from_ip = sock.recvfrom(4096)
        p = Packet(data)
        print p

class Sender(object):
    def __init__(self, ip='127.255.255.255', port=3000):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.ip = (ip, port)

    def send(self, data):
        self.sock.sendto(data, self.ip)

if __name__ == "__main__":
    l = Listener()
    l.start()
    s = Sender()
    p = Packet()
    p.packet_type = 4
    p.payload = 'jake'
    s.send(p.pack())

Arbeitslösung:

class MySender(DatagramProtocol):
    def __init__(self, packet, host='127.255.255.255', port=3000):
        self.packet = packet.pack()
        self.host = host
        self.port = port

    def startProtocol(self):
        self.transport.write(self.packet, (self.host, self.port))

if __name__ == "__main__":
    packet = Packet()
    packet.packet_type = 1
    packet.payload = 'jake'

    s = MySender(packet)

    reactor.listenMulticast(3000, MyProtocol(), listenMultiple=True)
    reactor.listenMulticast(3000, s, listenMultiple=True)
    reactor.callLater(4, reactor.stop)
    reactor.run()

Antworten auf die Frage(4)

Ihre Antwort auf die Frage