Suponiendo que está utilizando el módulo de socket estándar, debería detectar la excepción socket.error: (32, 'Broken pipe')
(no IOError como otros han sugerido). Esto se generará en el caso que haya descrito, es decir, que esté enviando/escribiendo a un socket para el cual el lado remoto se ha desconectado.
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
Tenga en cuenta que esta excepción no siempre se planteó en la primera escritura a una toma cerrada - más generalmente la segunda escritura (a menos que el número de bytes escritos en la primera escritura es más grande que el tamaño del búfer de la toma). Debe tener esto en cuenta en caso de que su aplicación considere que el extremo remoto recibió los datos de la primera escritura cuando ya se haya desconectado.
Puede reducir la incidencia (pero no eliminar completamente) de esto utilizando select.select()
(o poll
). Verifique que haya datos listos para leer por el par antes de intentar escribir. Si select
informa que hay datos disponibles para leer desde el socket par, léalo usando socket.recv()
. Si esto devuelve una cadena vacía, el par remoto ha cerrado la conexión. Debido a que todavía hay una condición de carrera aquí, igual tendrá que atrapar y manejar la excepción.
Twisted es ideal para este tipo de cosas, sin embargo, parece que ya ha escrito un poco de código.
Si hago una prueba: # algo, excepto: # cualquier cosa, ¿captará algo, y no solo IOErrors? –
La manta excepto es una mala política. Sin embargo, detectará cualquier tipo de excepción. Usted sabe que es un IOError. Maneja eso. Si surge algo más, descubra por qué y trátelo apropiadamente. No desea enmascarar errores como la división por cero o la falta de memoria. –
Si está utilizando el módulo de socket de Python, no obtendrá una excepción IOError: obtendrá una excepción socket.error. – mhawke