Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Читайте на попытке: оператор.
try:
# do something
except socket.error, e:
# A socket error
except IOError, e:
if e.errno == errno.EPIPE:
# EPIPE error
else:
# Other error
Предположение, что Вы используете стандартный модуль сокета, необходимо ловить socket.error: (32, 'Broken pipe')
исключение (не IOError, как другие предположили). Это будет повышено в случае, который Вы описали, т.е. отправляющий/пишущий к сокету, для которого разъединилась удаленная сторона.
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
Примечание, что это исключение будет не всегда повышаться на первой записи до закрытого сокета - чаще вторая запись (если число байтов, записанных в первой записи, не будет больше, чем размер буфера сокета). Необходимо иметь это в виду в случае, если приложение думает, что удаленный конец получил данные из первой записи, когда это, возможно, уже разъединилось.
можно уменьшить падение (но не полностью устранить) этого при помощи select.select()
(или poll
). Проверьте на данные, готовые читать от коллеги прежде, чем делать попытку записи. Если select
отчеты, что существуют доступные данные для чтения из сокета однорангового узла, читают его с помощью socket.recv()
. Если это возвращает пустую строку, удаленный узел закрыл соединение. Поскольку существует все еще состояние состязания здесь, необходимо будет все еще поймать и обработать исключение.
Скрученный является большим для этого вида вещи, однако, это кажется, что Вы уже записали немного кода.
SIGPIPE
(хотя я думаю, возможно, что Вы имеете в виду EPIPE
?) происходит на сокетах, когда Вы закрываете сокет и затем отправляете данные в них. Простое решение не должно завершать работу сокета прежде, чем попытаться отправить ему данные. Это может также произойти на каналах, но это не кажется, что это - то, что Вы испытываете, так как это - сетевой сервер.
можно также просто применить лейкопластырь ловли исключения в некотором обработчике верхнего уровня в каждом потоке.
, Конечно, если бы Вы использовали Скрученный вместо того, чтобы породить новый поток для каждого соединения клиента, у Вас, вероятно, не было бы этой проблемы. Действительно трудно (возможно, невозможный, в зависимости от Вашего приложения) получить упорядочивание операций закрытия и операций записи, корректных, если несколько потоков имеют дело с тем же каналом ввода-вывода.
Мой ответ очень близко к S.Lott's, кроме я был бы еще более конкретным:
try:
# do something
except IOError, e:
# ooops, check the attributes of e to see precisely what happened.
if e.errno != 23:
# I don't know how to handle this
raise
, где "23" код ошибки, Вы добираетесь от EPIPE. Таким образом, Вы не попытаетесь обработать ошибку полномочий или что-либо еще, для чего Вы не снабжены.