Python сокет зависает странно - иногда (клиент соединяется с flash) - python 3.2 - PullRequest
3 голосов
/ 14 июля 2011

Я испытываю странное поведение сокетов в Python (3.2).Клиент подключается к моему приложению с помощью Flash.В большинстве случаев в этом нет ничего необычного, но иногда происходит сбой питона, который не должен был происходить - входить в бесконечные циклы.Ниже я прилагаю к циклу код и сообщение об ошибке в журнале.Python зависает на bytesRecived = sock.recv(64) и получает b'' ведьму, видимую в журнале.

код:

try:
    buff = ''
    allBytesRecived = []
    timeout = sock.gettimeout()
    sock.settimeout(10.0)
    tries = 0
    while len(buff) < 64 and tries < 64:
        tries += 1
        bytesRecived = sock.recv(64)
        allBytesRecived.append(bytesRecived)
        comm = str(bytesRecived, config.encoding)
        buff += comm

        #flash connection and his strage security policy
        if buff[:24] == config.flash.policy_request:
            cross = open(config.flash.crossdomain,'rb').read()
            cross+=b'\x00' #end string
            sock.send(cross);
            raise FlashCrossdomainException()

    if len(buff) < 64:
        logger.critical('Hanged! buff=%s bytes=%s timeout=%s' % (repr(buff), repr(allBytesRecived), repr(sock.gettimeout())))
        raise InvalidSessionException('Unknown error')
    sock.settimeout(timeout)

except FlashCrossdomainException as e:
    raise e
except socket.timeout:
    raise InvalidSessionException('Timeout on signing in to system')
except socket.error as e:
    logger.exception(e)
    raise InvalidSessionException('Unknown IO error')
except Exception as e:
    logger.exception(e)
    raise InvalidSessionException('Unknown error')

ошибка журнала:

CRITICAL: Hanged! buff='' bytes=[b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b''] timeout=10.0

1 Ответ

0 голосов
/ 14 июля 2011

Модуль socket Python полностью соответствует API сокета BSD.

Когда удаленная сторона сокета (здесь ваш Flash-клиент) закрыта, вызов recv() на локальной стороне (здесь,ваш сервер Python) вернет пустую строку ('').нет необходимости продолжать обработку, так как клиент больше ничего не отправляет: канал закрыт.

с другой стороны, поскольку ваш сокет неблокируемый, если тайм-аут сокета происходит из-за того, что клиент не отправляет никаких данных в течение указанного времени (10 секунд), то вызов recv() вызовет повышениеsocket.timeout исключение, которое вы можете перехватить и обработать соответствующим образом.

вы должны добавить тест после recv() вызова:

bytesRecived = sock.recv(64)
if not len(bytesRecived):
    raise InvalidSessionException('connection reset')
...