Tengo una aplicación, Software Defined Radio, que transmite paquetes UDP en un puerto que decirle a los oyentes qué frecuencia y modo de demodulación se han establecido (entre otras cosas).Python y UDP escuchando
He escrito una demo cliente de python (código a continuación) que escucha el puerto y descarga la información en los paquetes apropiados a la consola.
Ambos funcionan bajo OSX 10.6, Snow Leopard. Ellos trabajan allí.
La pregunta/problema que tengo es: la aplicación Python debe iniciarse antes de la aplicación de radio o afirma que el puerto ya está en uso (ERRNO 47) durante el enlace, y no entiendo por qué. La aplicación de radio está transmitiendo UDP; ciertamente quiero acomodar a múltiples oyentes: esa es la idea de la radiodifusión, o al menos, así lo pensé.
Así que aquí está el código Python (el guión es un poco desordenado debido al desbordamiento de pila es muy tonto "hacer-él-código" guión, pero le aseguro que está bien):
#!/usr/bin/python
import select, socket
# AA7AS - for SdrDx UDP broadcast
# this is a sample python script that captures the UDP messages
# that are coming from SdrDx. SdrDx tells you what frequency and
# mode it has been set to. This, in turn, would be used to tell
# another radio to tune to that frequency and mode.
# UDP packet from SdrDx is zero terminated, but receiving the
# packet makes it seem like the string contains zeros all the
# way out to the 1024th character. This function extracts a
# python string up to the point where it hits the first zero,
# then returns that string.
# -----------------------------------------------------------
def zeroterm(msg):
counter = 0;
for c in msg:
if ord(c) != 0:
counter += 1
strn = msg[:counter]
return strn
port = 58083 # port where we expect to get a msg
bufferSize = 1024 # room for message
# Create port to listen upon
# --------------------------
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.bind(('', port))
except:
print 'failure to bind'
s.close()
raise
s.setblocking(0)
# Listen for messages
# -------------------
looping = True
while looping:
try:
result = select.select([s],[],[])
except: # you can kill the client here with control-c in its shell
s.close() # must close socket
print 'Closing, exception encountered during select' # warn
raise SystemExit # and quit
msg = result[0][0].recv(bufferSize) # actually fetch the UDP data
msg = zeroterm(msg) # convert content into python string
# in next line, [] contain optional repeats
# message format is keyword:data[|keyword:data]
# where from 1...n keyword:data pairs may appear, up to 1024 bytes
# ----------------------------------------------------------------
try:
msgs = msg.split('|') # can be more than one message in packet
except: # failed to split
msgs = [] # on the other hand, can just be one. :)
msgs.append(msg) # so build array with that one.
for m in msgs: # now, for every message we have
keyw,data = m.split(':') # break into keyword and data
print keyw + "-->" + data # you'd do something with this
if keyw == "closing": # Our client terminates when SdrDx does
looping = False # loop stops
s.close() # must close socket
print 'Normal termination'
Como referencia, aquí está el código de Qt que está enviando el mensaje UDP:
Configuración:
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 is full of zeroes
strcpy(datagram->data(),msg); // except where text message is in it at beginning
udpSocketSend->writeDatagram(*datagram, QHostAddress::Broadcast,txudp); // send
}
Estas dos aplicaciones se están ejecutando en la misma máquina, ¿sí? – jedwards
Debe corregir la sangría. Después de 'try:' no puede haber una línea que tenga el mismo nivel de sangría que la instrucción 'try:'. – ThiefMaster
@jedwards, sí. ThiefMaster: como dije explícitamente justo encima del código de Python, el formateo de stackoverflow ensuciaba la sangría. El código está sangrado correctamente. No hay preocupaciones allí. – fyngyrz