Python and UDP listening -
i have app, software defined radio, broadcasts udp packets on port tell listeners frequency , demodulation mode have been set (among other things.)
i've written demo python client (code below) listens port, , dumps out information in appropriate packets console.
these both running under osx 10.6, snow leopard. work there.
the question/issue have is: python app has started before radio app or claims port in use (errno 47) during bind, , don't understand why. radio app broadcasting udp; want accommodate multiple listeners -- that's idea of broadcasting, or @ least, thought.
so here's python code (the indent little messed due stack overflow's dumb "make-it-code" indent, assure it's ok):
#!/usr/bin/python import select, socket # aa7as - sdrdx udp broadcast # sample python script captures udp messages # coming sdrdx. sdrdx tells frequency , # mode has been set to. this, in turn, used tell # radio tune frequency , mode. # udp packet sdrdx 0 terminated, receiving # packet makes seem string contains zeros # way out 1024th character. function extracts # python string point hits first zero, # returns string. # ----------------------------------------------------------- def zeroterm(msg): counter = 0; c in msg: if ord(c) != 0: counter += 1 strn = msg[:counter] return strn port = 58083 # port expect msg buffersize = 1024 # room message # create port listen upon # -------------------------- s = socket.socket(socket.af_inet, socket.sock_dgram) try: s.bind(('', port)) except: print 'failure bind' s.close() raise s.setblocking(0) # listen messages # ------------------- looping = true while looping: try: result = select.select([s],[],[]) except: # can kill client here control-c in shell s.close() # must close socket print 'closing, exception encountered during select' # warn raise systemexit # , quit msg = result[0][0].recv(buffersize) # fetch udp data msg = zeroterm(msg) # convert content python string # in next line, [] contain optional repeats # message format keyword:data[|keyword:data] # 1...n keyword:data pairs may appear, 1024 bytes # ---------------------------------------------------------------- try: msgs = msg.split('|') # can more 1 message in packet except: # failed split msgs = [] # on other hand, can one. :) msgs.append(msg) # build array one. m in msgs: # now, every message have keyw,data = m.split(':') # break keyword , data print keyw + "-->" + data # you'd if keyw == "closing": # our client terminates when sdrdx looping = false # loop stops s.close() # must close socket print 'normal termination' for reference, here's qt code sending udp message:
setup:
bcast = new qhostaddress("192.168.1.255"); if (bcast) { udpsocketsend = new qudpsocket(0); if (udpsocketsend) { udpsocketsend->bind(*bcast, txudp); } } broadcast:
if (udpsocketsend) { qbytearray *datagram = new qbytearray(1024,0); // datagram full of zeroes strcpy(datagram->data(),msg); // except text message in @ beginning udpsocketsend->writedatagram(*datagram, qhostaddress::broadcast,txudp); // send }
you trying bind same port, twice.
you bind once in sender:
if (udpsocketsend) { udpsocketsend->bind(*bcast, txudp); } and again @ receiver
s.bind(('', port)) and since these running on same machine, getting error.
unless care source port is, don't need bind() on sender, send , stack pick appropriate outgoing source port number. in case of sender, when transmit udp datagram specify destination (udpsocketsend->writedatagram(...)), , bind determines source of outgoing datagram. if don't bind, thats fine, stack assign port.
if do care source port is, suggest use different port number outgoing source port , incoming destination port. able bind both sender , receiver without issue.
lastly, there option set so_reuseaddr socket option (in whatever language you're using). necessary if want run multiple clients on same machine, clients have bind same address. but, i'm not sure whether socket option cross platform (*nix works fine) , think above suggestions better.
Comments
Post a Comment