receiving messages without blocking the code

Hello,

I am new to code on python (and on C) and I couldnt figure this out myself:

Is there a way to use the recvfrom() function with less blocking way. I mean, if I write like in the example:

from socket import *
sd = socket(AF_ZIGBEE, SOCK_DGRAM, ZBS_PROT_TRANSPORT)
sd.bind((“”, 0xe8, 0, 0))
payload, src_addr = sd.recvfrom(72)

Then if nothing is received (a.k.a node is not responding at that moment), everything gets totally blocked on line 4. I want to skip the receiving if there comes no response in some certain time limit. So I tried to use the while loop something like

timestart=time.clock()
timelimit=timestart+10

while timenow

Hello!

I think socket has a method to set a timeout, try with:

sd.settimeout(5.0)

Where 5.0 is the maximum time (in seconds) the socket will be waiting for data.

Hope it helps.

Regards.

Two alternatives include using non-blocking sockets (which isn’t recommended in this case, since you actually do intend to wait for at least some period of time), or the “select” module. The “select” module offers the semantics you seek (wait for the socket to become readable until a timeout) with the advantage that it can be used (in more complex environments) to keep track of multiple sockets simultaneously in a single thread.

Hey,

Thank you Diego, that was exactly what I needed!

Is there a list of that kind of options somewhere since digipython programming guide doesn’t mention for example this settimeout()-function?

Best Regards
-Matalalento-

For questions like these, regarding potentially available features in standard Python modules, the Python library documentation is the best place to turn. For instance, the documentation for the “socket” object in the socket module for Python 2.4.3 is found here:

http://www.python.org/doc/2.4.3/lib/socket-objects.html

There are some exceptions to standard behaviors when running in the embedded environment… Digi continues to make efforts to improve the completeness of this sort of documentation.

Hello,

Thank you for giving me those hints and alternatives. I became interested in select() module now, because I would like to try a little more complex environment than just gateway and one node. Could you give me a bit advice on how to use this select() module?
If I want to add 2 or more series 2 radios (with loopback testers) to the network with gateway and just send something to them and receive answer, how should i use this module? I know how to do it with one radio:

#-------------------------------------------------------
addy = (“xx:xx:xx:xx:xx:xx:xx:xx!”,
0xe8, 0xc105, 0x11)

sd = socket(AF_ZIGBEE, SOCK_DGRAM, ZBS_PROT_TRANSPORT)

sd.bind((“”, 0xe8, 0, 0))
sd.settimeout(5.0)

try:
sd.sendto(“123”, 0, addy)
data, src_addr = sd.recvfrom(72)

except:
print “no connection”
#-------------------------------------------------------

So how would the select() change this? Do I still bind every endpoint under different name like the “sd”. I looked at the section for the select() module in the link you gave me above but couldnt really figure it out myself.

Thank you
-Matalalento-

Since the communication in this is “connectionless” (i.e. sendto / recvfrom are used, connect is not, generally), and you probably want all of your transmissions from our device to have a source address with the same endpoint, you would only bind once, and you multiplex the different endpoints at your application level… possibly using the remote address (from recvfrom) as a key.

Select would be very appropriate if you, in turn, were pushing the data to external TCP or UDP endpoints on the network… those sockets could be managed in the same select as your AF_ZIGBEE socket.