Twisted UDP - Почему я не могу отправить без прослушивания? - PullRequest
0 голосов
/ 31 октября 2019

Как отправить без вызова Reactor.ListenUDP? Если я попытаюсь, то получу исключение в классе протокола, что транспорт равен NULL. Кажется, он не будет настроен в базовом классе, пока вы не вызовете реактор. ListenUDP. Конечно, у вас есть возможность отправлять без прослушивания входящих сообщений. В конце концов, сервер может вообще не хотеть получать.

---- main.py ------

import wx
from twisted.internet import wxreactor
from main_window import MainWindow


def main():
    app = wx.App(False)
    frame = MainWindow(None, 'UDP Demo')

    from twisted.internet import reactor
    reactor.registerWxApp(app)
    reactor.run()


if __name__ == "__main__":
    wxreactor.install()
    main()

--- main_window.py---

# SNIP - Nothing really relevant. Just creates the classes below and hooks up buttons to call their methods

--- plugin.py ----

from enum import Enum
from twisted.internet.error import CannotListenError

from udp_protocol import UDPProtocol


class PluginBase(object):
    """
    This is just a dummy class to match what is in Falco
    """

    def __init__(self, app_dist, *args, **kwargs):
        pass


class Plugin(PluginBase):
    class State(Enum):
        """
        Represents the states that the plugin can be in
        """
        CLOSED = 0                     # Initial state
        LISTENING = 1                  # After open() is called
        RECV_CALLBACK_REGISTERED = 2   # After listen() is called

    def __init__(self, app_dist, *args, **kwargs):
        super(Plugin, self).__init__(app_dist, *args, **kwargs)
        self.state = self.State.CLOSED
        self.port = None
        self.listener = None
        self.listen_callback = None
        self.protocol = UDPProtocol(self.on_data_received)

    def listen(self, port, isBroadcast, callback, errback=None):
        if self.state != self.State.CLOSED:
            raise RuntimeError("UDP Plugin already in an opened state")
        self.port = port

        # Start listening
        try:
            from twisted.internet import reactor
            self.listener = reactor.listenUDP(self.port, self.protocol)
            self.state = self.State.LISTENING
            callback()
        except CannotListenError as err:
            error_json = {"error": err[2].strerror}
            if errback is not None:
                errback(error_json)

    def stop_listening(self):
        if self.listener is not None:
            self.listener.stopListening()
            self.listener = None

        self.listen_callback = None
        self.port = None
        self.state = self.State.CLOSED

    def send(self, addr, port, data):
        # While it seems like one could send without listening for incoming messages,
        # twisted's implementation doesn't seem to work that way?
        # The transport in the protocol object only gets created when we call reactor.listenUDP,
        # as far as I can tell
        if self.state == self.State.CLOSED:
            raise RuntimeError(
                "UDP Plugin must be in an open state before attempting to send")

        self.protocol.send(addr, port, data)

    # SNIP recv

---- udp_protocol.py ---

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor


class MyProtocol(DatagramProtocol):

    def datagramReceived(self, data, (host, port)):
        print "received %r from %s:%d" % (data, host, port)
        self.transport.write(data, (host, port))

    def send(self, addr, port, data):
        self.transport.write(data, (addr, port))

1 Ответ

1 голос
/ 02 ноября 2019

Конечно, у вас есть возможность отправлять без прослушивания входящих сообщений.

Как оказалось, нет. Однако ничто не заставляет вас что-либо делать с поступающими входящими сообщениями.

...