扭曲的UDP-为什么我不能不听就发送?

时间:2019-10-31 20:30:24

标签: python udp twisted

如何在不调用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 个答案:

答案 0 :(得分:1)

  

当然,您可以发送而无需侦听传入的消息。

事实证明,没有。但是,没有什么可以强迫您对收到的任何传入消息进行任何处理。