<div>Hi all,</div><div> </div><div><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">After reading the </span><a style="text-decoration:none;" href="http://twistedmatrix.com/documents/current/core/howto/udp.html"><u style="background-color:transparent;color:#1155cc;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;">UDP Networking</u></a><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;"> how-to I added interaction using UDP messages to my distributed application. One sub-application is UDP broadcaster and the other one is responder. </span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">Their minimized code is below:</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><strong style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:700;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">broadcaster.py:</strong></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">from datetime import datetime</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">import socket</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">import traceback</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">from twisted.internet import task, reactor</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">from twisted.internet.protocol import DatagramProtocol</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">DEFAULT_PORT = 2017</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">DEFAULT_HOST = "192.168.2.255"</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">DEFAULT_INTERVAL_SECONDS = 1</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">class BroadcasterProtocol(DatagramProtocol):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   def __init__(self, port):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       self._port = port</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   def startProtocol(self):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       print "BroadcasterProtocol::startProtocol"</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       self.transport.setBroadcastAllowed(True)</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   def broadcastTime(self):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       time_str = datetime.now().time().strftime("%H:%M:%S.%f")</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       try:</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">           self.transport.write(time_str.encode('utf-8'), ('<broadcast>', self._port))</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">           print "BroadcasterProtocol: broadcasted time: {}".format(time_str)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       except Exception:</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">           print "BroadcasterProtocol: time sending failed!"</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   def datagramReceived(self, datagram, addr):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       print "BroadcasterProtocol: datagram from {} received:\n{}".format(addr, datagram)</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">def loopDone(unused):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   print "Loop done"</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">def loopFailure(failure):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   print "Loop failure! Failure is {}".format(traceback.format_exc(failure))</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   </span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">protocol = BroadcasterProtocol(DEFAULT_PORT)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">the_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">the_socket.setblocking(False)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">the_socket.bind((DEFAULT_HOST, DEFAULT_PORT))</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">twisted_port = reactor.adoptDatagramPort(the_socket.fileno(), socket.AF_INET, protocol)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">loop = task.LoopingCall(protocol.broadcastTime)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">d = loop.start(DEFAULT_INTERVAL_SECONDS)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">d.addCallback(loopDone).addErrback(loopFailure)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">reactor.run()</span></strong></p><br /><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><strong style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:700;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">responder.py:</strong></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">from twisted.internet import reactor</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">from twisted.internet.protocol import DatagramProtocol</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">DEFAULT_PORT = 2017</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">class ResponderProtocol(DatagramProtocol):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">   def datagramReceived(self, data, addr):</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       print "ResponderProtocol: received from {addr}:\n{data}".format(</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">           addr = addr, data = data)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       response = "GOT " + data</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       print "ResponderProtocol: sending response \"{response}\" to address {addr}".format(</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">           response = response, addr = addr)</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">       self.transport.write(response, addr)</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">responder_port = reactor.listenUDP(DEFAULT_PORT, ResponderProtocol())</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">reactor.run()</span></strong></p> <p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">There are some reasons why I implemented UDP broadcasting and responding in the way that is a bit different than that shown in </span><a style="text-decoration:none;" href="http://twistedmatrix.com/documents/current/_downloads/udpbroadcast.py"><u style="background-color:transparent;color:#1155cc;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;">the official udpbroadcast.py example</u></a><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">, but after reading </span><a style="text-decoration:none;" href="http://twistedmatrix.com/documents/current/core/howto/udp.html"><u style="background-color:transparent;color:#1155cc;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;">UDP Networking</u></a><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;"> how-to I thought this isn’t important.</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">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.</span></strong></p><p style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><strong style="font-weight:normal;"><span style="background-color:transparent;color:#000000;font-family:arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">Is this a bug or I made something wrong?</span></strong></p></div><div> </div><div>-- </div><div>Kind regards, Roman Mescheryakov</div><div> </div>