Python socket 奇怪地挂起 - 有时(客户端与Flash连接) - python 3.2

3 投票
1 回答
594 浏览
提问于 2025-04-16 21:30

我在使用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

Python的socket模块和BSD的socket API很相似。

当一个socket的远端(在这里指的是你的Flash客户端)关闭时,调用本地的recv()方法(这里是你的Python服务器)会返回一个空字符串('')。这时候就不需要再继续处理了,因为客户端不会再发送任何数据:通道已经关闭。

另一方面,由于你的socket是非阻塞的,如果因为客户端在规定的时间内(10秒)没有发送任何数据而发生了socket超时,那么recv()方法会抛出一个socket.timeout异常,你可以捕获这个异常并进行相应的处理。

recv()调用之后,你应该添加一个测试:

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

撰写回答