Я пытаюсь отслеживать исключение тайны из socket.recv(), у которого нет сообщения, чтобы дать представление о том, откуда он или почему. Это на Windows 7, Python 2.7.Исключение без информации из блокирующего сокета в Python
создать блокирующий сокет так:
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.settimeout(5)
подключить к части оборудования, потоки данных из. Я никогда ничего не посылаю через этот сокет, я получаю только. Поэтому я вращаюсь в цикле вызова select:
while(True):
# Process commands from the GUI. These can include requests to
# connect, disconnect, or quit
quitting = self.processCmds()
if quitting == True:
print 'exiting'
return
try:
rlist, wlist, errlist = select.select([self.client], [], [self.client], 5)
if self.client in errlist:
self.reconnect()
continue
elif self.client in rlist:
# We have a message.
msg = recvall(self.client, MESSAGE_LENGTH)
if msg == None:
self.reconnect()
continue
Пока что так хорошо. rcvall() крутится в цикле так, как и следовало ожидать, пытаясь прочитать запрошенное количество байт:
def recvall(conn, count):
buf = b''
numIterations = 0
while count:
try:
recvString = conn.recv(count)
except:
# OH NO SOMETHING BAD HAPPENED!
e = sys.exc_info()[0]
return None
if not recvString:
# the socket has been closed by the remote end
return None
if (len(recvString) > 0):
buf = buf + recvString
count = count - len(recvString)
else:
# If the other guy has sent no bytes, don't wait forever
numIterations += 1
if numIterations > 100:
return None
return buf
Так что, если что-то пойдет не так, recvall() не возвращает None, который сообщает абоненту, чтобы закрыть существующий подключиться и открыть новый.
Это работает красиво около 8 часов или около того, но затем я вижу поток попыток повторного подключения в моем журнале, но ничего не получается. После некоторой охоты и клевания с контрольными точками я узнаю, что мы делаем исключение в rcvall(), где комментарий OH NO SOMETHING BAD HAPPENED! является. Но когда я пытаюсь проверить объект исключения в отладчике, его элемент сообщения - «Нет». На самом деле, все его члены - Ники, поэтому нет никакого понятия о том, кто его поднимает или почему.
Есть несколько странных вещей об этом. Исключение происходит ПОСЛЕ того, как select() уже сказал мне, что сокет является безошибочным и содержит данные. Может ли что-то пойти не так между вызовом select() и вызовом recvall()? Это возможно, но вряд ли кажется вероятным.
второй, кто-нибудь видел такое странное исключение, исходящее из socket.recv? Любой ключ, где его искать?
Исключение может иметь полезную информацию, неясно, распечатываете ли вы ее. Это было бы первым делом. Во-вторых, если клиент отключается, вы можете обнаружить его только при попытке чтения/записи. Это странность API-интерфейса сокета UNIX TCP/IP, но выбор не скажет вам об этом. См. Http://stackoverflow.com/questions/283375/detecting-tcp-client-disconnect – rts1
Хорошее предложение. Я думаю, что моя следующая яркая идея - удалить catch для этого исключения и запустить его без IDE. Возможно, трассировка командной строки будет более познавательной, чем показывает IDE. Иногда Visual Studio + PTVS смешно рассказывать вам всю историю, когда происходит исключение. Я подозреваю, что что-то не так на другом конце, и, возможно, больше информации. об этом исключении скажут мне, что это такое. – user2623722