Python套接字被绞死 - 有时(客户端连接闪存) - python 3.2

时间:2011-07-14 11:44:32

标签: python flash sockets

我在Python(3.2)中遇到套接字的奇怪行为。客户端使用Flash连接到我的应用程序。大多数时候没有什么不寻常的,但有时python崩溃的方式不应该发生 - 进入无限循环。下面我附上日志中的循环代码和错误消息。 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 :(得分:0)

python的socket模块与BSD套接字API紧密匹配。

当套接字的远程端(此处为您的Flash客户端)关闭时,本地端(此处为您的python服务器)的recv()调用将返回一个空字符串('') 。没有必要继续处理,因为客户端不会发送更多信息:频道已关闭。

另一方面,由于您的套接字是非阻塞的,如果由于客户端在指定的时间限制(10秒)内未发送任何数据而发生套接字超时,则recv()调用将引发socket.timeout异常,您可以捕获并相应地处理。

您应该在recv()电话后添加测试:

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