After reading the UDP Networking how-to I added interaction using UDP messages to my distributed application. One sub-application is UDP broadcaster and the other one is responder.
Their minimized code is below:
broadcaster.py:
from datetime import datetime
import socket
import traceback
from twisted.internet import task, reactor
from twisted.internet.protocol import DatagramProtocol
DEFAULT_PORT = 2017
DEFAULT_HOST = "192.168.2.255"
DEFAULT_INTERVAL_SECONDS = 1
class BroadcasterProtocol(DatagramProtocol):
def __init__(self, port):
self._port = port
def startProtocol(self):
print "BroadcasterProtocol::startProtocol"
self.transport.setBroadcastAllowed(True)
def broadcastTime(self):
time_str = datetime.now().time().strftime("%H:%M:%S.%f")
try:
self.transport.write(time_str.encode('utf-8'), ('<broadcast>', self._port))
print "BroadcasterProtocol: broadcasted time: {}".format(time_str)
except Exception:
print "BroadcasterProtocol: time sending failed!"
def datagramReceived(self, datagram, addr):
print "BroadcasterProtocol: datagram from {} received:\n{}".format(addr, datagram)
def loopDone(unused):
print "Loop done"
def loopFailure(failure):
print "Loop failure! Failure is {}".format(traceback.format_exc(failure))
protocol = BroadcasterProtocol(DEFAULT_PORT)
the_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
the_socket.setblocking(False)
the_socket.bind((DEFAULT_HOST, DEFAULT_PORT))
twisted_port = reactor.adoptDatagramPort(the_socket.fileno(), socket.AF_INET, protocol)
loop = task.LoopingCall(protocol.broadcastTime)
d = loop.start(DEFAULT_INTERVAL_SECONDS)
d.addCallback(loopDone).addErrback(loopFailure)
reactor.run()
responder.py:
from twisted.internet import reactor
from twisted.internet.protocol import DatagramProtocol
DEFAULT_PORT = 2017
class ResponderProtocol(DatagramProtocol):
def datagramReceived(self, data, addr):
print "ResponderProtocol: received from {addr}:\n{data}".format(
addr = addr, data = "">
response = "GOT " + data
print "ResponderProtocol: sending response \"{response}\" to address {addr}".format(
response = response, addr = addr)
self.transport.write(response, addr)
responder_port = reactor.listenUDP(DEFAULT_PORT, ResponderProtocol())
reactor.run()
There are some reasons why I implemented UDP broadcasting and responding in the way that is a bit different than that shown in the official udpbroadcast.py example, but after reading UDP Networking how-to I thought this isn’t important.
ResponderProtocol.datagramReceived is successfully called with messages sent by broadcaster. Also I expected BroadcasterProtocol.datagramReceived to be called with “GOT <time>” responses sent by ResponderProtocol, but this doesn’t take place. Using strace I can see that sendto system function is being called by the responder process with “GOT <time>” messages, but there are no corresponding recv* calls in the broadcaster process.
Is this a bug or I made something wrong?
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python