2011-06-16 19 views
9

Soy nuevo en Python y actualmente tengo que escribir un socket python para ejecutarlo como un script que se comunica con un dispositivo a través de TCP/IP (una estación meteorológica).
El dispositivo actúa como el lado del servidor (escuchando por IP: PUERTO, aceptando conexión, recibiendo solicitud, transfiriendo datos).
Solo necesito enviar un mensaje, recibir la respuesta y luego apagar pacíficamente y bien y cerrar el socket. Python: socket no bloqueante o Asincronos E/S

try: 
    comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
except socket.error, msg: 
    sys.stderr.write("[ERROR] %s\n" % msg[1]) 
    sys.exit(1) 

try: 
    comSocket.connect(('')) 
except socket.error, msg: 
    sys.stderr.write("[ERROR] %s\n" % msg[1]) 
    sys.exit(2) 

comSocket.send('\r') 
comSocket.recv(128) 
comSocket.send('\r') 
comSocket.recv(128) 
comSocket.send('\r\r') 
comSocket.recv(128) 

comSocket.send('1I\r\r3I\r\r4I\r\r13I\r\r5I\r\r8I\r\r7I\r\r9I\r\r') 

rawData = comSocket.recv(512) 

comSocket.shutdown(1) 
comSocket.close() 

El problema que estoy teniendo es:
El canal de comunicación es fiable, el dispositivo es lento. Por lo tanto, a veces la respuesta del dispositivo con un mensaje de longitud 0 (solo un ACK), mi código se congelará y esperará la respuesta para siempre.
Este fragmento de código contiene la parte que implica SOCKET, todo el código se ejecutará bajo CRON, por lo que la congelación no es un comportamiento deseable.

Mi pregunta es:
¿Cuál sería la mejor manera en Python para manejar ese comportamiento, por lo que el código no se congela y esperar para siempre, pero se tratará de pasar a la próxima emisión (o tal) .

+5

Debería echar un vistazo a la biblioteca [Twisted] (http://twistedmatrix.com/) para Python. Es un marco para redes asíncronas que lo haría mucho más fácil. – Andrea

+0

Si bien el uso de la biblioteca Twisted puede funcionar, toda una biblioteca para un mensaje parece un poco exagerada. Quizás necesite que CRON abra un subproceso con su comunicación de socket en un hilo separado. De esa forma evitarás el problema del bloqueo. – chisaipete

+0

@Andrea ya que tengo una pregunta similar a la publicada. ¿Twisted no está diseñado para el lado del servidor? ¿Cómo modificarlo para usar en el lado del cliente? – Hangon

Respuesta

0

intento, antes de recibir, poner un tiempo de espera en el zócalo:

comSocket.settimeout(5.0) 
try: 
    rawData = comSocket.recv(512) 
except socket.timeout: 
    print "No response from server" 
3

lo recomiendo eventlet y los hilos verdes para esto.

Twisted es una buena biblioteca pero una curva de aprendizaje un poco empinada para un caso de uso tan simple.

Vea algunos ejemplos here.

11

Puede probar un enfoque de tiempo de espera, como el código Russel o puede usar un socket no bloqueante, como se muestra en el siguiente código. Nunca se bloqueará al socket.recv y puede usarlo dentro de un ciclo para volver a intentarlo tantas veces como desee. De esta forma, su programa no se bloqueará en el tiempo de espera. De esta forma, puede probar si hay datos disponibles y si no, puede hacer otras cosas y volver a intentarlo más tarde.

socket.setblocking(0) 
while (retry_condition): 
    try: 
     data = socket.recv(512) 
    except socket.error: 
     '''no data yet..''' 
Cuestiones relacionadas