Angenommen, Sie verwenden das Standard-Socket-Modul, sollten Sie die Ausnahme socket.error: (32, 'Broken pipe')
fangen (nicht IOError, wie andere vorgeschlagen haben). Dies wird in dem Fall ausgelöst, den Sie beschrieben haben, d. H. Senden/Schreiben an einen Socket, für den die entfernte Seite die Verbindung getrennt hat.
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
Beachten Sie, dass diese Ausnahme nicht immer auf den ersten Schreibvorgang in einer geschlossenen Buchse angehoben werden - mehr in der Regel die zweite Schreib (es sei denn, die Anzahl von Bytes in dem ersten Schreib geschrieben ist größer als die Puffergröße des Sockets). Sie müssen dies im Hinterkopf behalten, wenn Ihre Anwendung der Ansicht ist, dass das entfernte Ende die Daten vom ersten Schreibvorgang empfangen hat, obwohl es möglicherweise bereits getrennt wurde.
Sie können die Häufigkeit reduzieren (aber nicht vollständig eliminieren), indem Sie select.select()
(oder poll
) verwenden. Suchen Sie nach Daten, die bereit sind, vom Peer gelesen zu werden, bevor Sie einen Schreibvorgang durchführen. Wenn select
meldet, dass Daten zum Lesen aus dem Peer-Socket verfügbar sind, lesen Sie es unter Verwendung von socket.recv()
. Wenn dies eine leere Zeichenfolge zurückgibt, hat die Gegenstelle die Verbindung geschlossen. Da es hier immer noch eine Wettlaufsituation gibt, müssen Sie die Ausnahme dennoch fangen und behandeln.
Twisted ist großartig für diese Art von Sache, aber es klingt, als ob Sie bereits ein gutes Stück Code geschrieben haben.
Wenn ich einen Versuch mache: #etwas außer: #anything, wird es nur irgendetwas fangen, und nicht nur IOErrors? –
Die Decke ist eine schlechte Politik. Aber es wird jede Art von Ausnahme fangen. Du weißt, es ist ein IOError. Regle dies. Wenn etwas anderes auftaucht, ergründen Sie warum und behandeln Sie es entsprechend. Sie wollen keine Fehler wie Division durch Null oder nicht genügend Speicher maskieren. –
Wenn Sie Pythons Socket-Modul verwenden, erhalten Sie keine IOError-Ausnahme: Sie erhalten eine socket.error Ausnahme. – mhawke