En supposant que vous utilisez le module de socket standard, vous devriez attraper l'exception socket.error: (32, 'Broken pipe')
(pas IOError comme d'autres l'ont suggéré). Cela sera déclenché dans le cas que vous avez décrit, c'est-à-dire en envoyant/en écrivant sur une socket pour laquelle le côté distant s'est déconnecté.
import socket, errno, time
# setup socket to listen for incoming connections
s = socket.socket()
s.bind(('localhost', 1234))
s.listen(1)
remote, address = s.accept()
print "Got connection from: ", address
while 1:
try:
remote.send("message to peer\n")
time.sleep(1)
except socket.error, e:
if isinstance(e.args, tuple):
print "errno is %d" % e[0]
if e[0] == errno.EPIPE:
# remote peer disconnected
print "Detected remote disconnect"
else:
# determine and handle different error
pass
else:
print "socket error ", e
remote.close()
break
except IOError, e:
# Hmmm, Can IOError actually be raised by the socket module?
print "Got IOError: ", e
break
Notez que cette exception ne sera pas toujours élevé sur la première écriture à une prise fermée - plus généralement la seconde écriture (à moins que le nombre d'octets écrits dans la première écriture est plus grande que la taille de la mémoire tampon de la prise). Vous devez garder cela à l'esprit au cas où votre application pense que l'extrémité distante a reçu les données de la première écriture alors qu'elle était déjà déconnectée.
Vous pouvez réduire l'incidence (mais pas l'éliminer entièrement) en utilisant select.select()
(ou poll
). Vérifiez que les données sont prêtes à être lues par l'homologue avant d'essayer d'écrire. Si select
signale qu'il y a des données disponibles à lire à partir du socket homologue, lisez-le en utilisant socket.recv()
. Si cela renvoie une chaîne vide, l'homologue distant a fermé la connexion. Étant donné qu'il existe toujours une condition de concurrence, vous devrez toujours capturer et gérer l'exception. Twisted est idéal pour ce genre de chose, cependant, il semble que vous avez déjà écrit un peu de code.
Si je fais un essai: #quelque chose sauf: # quoi que ce soit, est-ce que ça va juste attraper n'importe quoi, et pas seulement IOErrors? –
La couverture sauf est une mauvaise politique. Mais encore, il va attraper n'importe quelle sorte d'exception. Vous savez que c'est un IOError. Gérer ce. Si quelque chose d'autre surgit, comprendre pourquoi et gérer de manière appropriée. Vous ne voulez pas masquer les bogues comme la division par zéro ou la mémoire. –
Si vous utilisez le module socket de Python, vous ne recevrez pas d'exception IOError: vous obtiendrez une exception socket.error. – mhawke