Как отправить без вызова 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))