J'écris une application en Python 2.7.5 en utilisant l'interface de socket brute (import socket
).
J'ai besoin de savoir s'il est possible d'enregistrer une sorte d'événement ou de tester facilement à intervalles réguliers, si une connexion socket TCP socket est toujours connectée et établie.
La plupart des conseils que j'ai trouvés disent des choses comme "essayez simplement de lire; s'il est fermé, vous obtiendrez une erreur ou aucun octet". Cependant, parfois je ne suis pas prêt à read
mais je veux quand même savoir si le socket est fermé, donc par exemple je peux me reconnecter manuellement immédiatement.
De plus, read
ing de la socket supprimerait les octets lus dans le tampon, donc read
ing simplement pour tester la "vivacité" de la connexion ne semble pas faisable.
Avoir un fil d'arrière-plan pour vérifier la vivacité de la connexion serait OK avec moi. Ce thread pourrait vérifier dis une fois par seconde pour voir si la connexion est active; s'il est abandonné, il pourrait appeler une fonction, ou définir une variable ou autre chose pour que l'application sache que la connexion est fermée. Savoir POURQUOI il s'est fermé (réinitialisation par un pair, timeout, etc.) serait encore plus utile ....
Un conseil à ce sujet?
Utilisez select
comme ce tutoriel le suggère http://docs.python.org/2/howto/sockets.html#non-blocking-sockets
Si un socket se trouve dans la liste lisible en sortie, vous pouvez être aussi proche de certain que nous en avons dans ce métier qu'un recv sur ce socket retournera quelque chose. Même idée pour la liste accessible en écriture. Vous pourrez envoyer quelque chose. Peut-être pas tout ce que vous voulez, mais quelque chose vaut mieux que rien. (En fait, tout socket raisonnablement sain retournera en écriture - cela signifie simplement que l'espace de tampon réseau sortant est disponible.)
... si quelque part dans ces listes d'entrée de sockets en est une qui est morte d'une mort désagréable, la sélection échouera.
C'est le flux que j'utilise habituellement
import select
import socket
ip = '127.0.0.1'
port = 80
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.connect((ip, port))
while True:
try:
ready_to_read, ready_to_write, in_error = \
select.select([conn,], [conn,], [], 5)
except select.error:
conn.shutdown(2) # 0 = done receiving, 1 = done sending, 2 = both
conn.close()
# connection error event here, maybe reconnect
print 'connection error'
break
if len(ready_to_read) > 0:
recv = conn.recv(2048)
# do stuff with received data
print 'received:', recv
if len(ready_to_write) > 0:
# connection established, send some stuff
conn.send('some stuff')