Python SOCKET 无限循环:栈溢出

0 投票
2 回答
1856 浏览
提问于 2025-04-17 21:09

我正在使用Blender游戏引擎制作一个游戏。我写了一个IRC脚本,在OS X和Linux系统上运行得很好。输出大概是这样的:

Logging in...
LOGIN_ERROR
LOGIN_ERROR
LOGIN_ERROR
LOGIN_ERROR
LOGIN_ERROR
LOGIN_ERROR
<name> has joined.
Logged in!

然后我可以调用我的sendmsg()函数来向IRC频道发送消息。

但是当我在Windows 7上运行时,出现了这个错误: stack overflow python sockets error

我的Python IRC代码在这里: http://pastebin.com/aG6TwTir

可以忽略“bge”的引用。这些变量是从游戏引擎中获取的。

在游戏引擎中,我调用login()一次,它会输出“LOGIN_ERROR”,所以我知道它在尝试连接,然后它会成功连接,因此不会抛出异常并结束这个函数。

在OS X和Linux上,它在后台完美无缝地运行,玩家可以继续游戏,而它在连接。

但是在Windows 7上,它就抛出了那个错误。

所以我想我需要做的是找到一种方法,让脚本等待连接到服务器。然后一旦连接成功,我就可以发送登录信息并加入频道。

那么,我该如何等待连接呢?

顺便说一下:我把套接字设置为非阻塞,因为脚本需要在与游戏引擎相同的线程上运行,每一帧都要执行。Main()每一帧都会运行,而不是整个脚本。在菜单中,它执行脚本并调用login()。然后一旦进入游戏,它会每一帧调用Main()。

哦,我使用的是Python 3.3。

任何帮助都非常感谢!^_^

编辑: 我该如何处理这个异常? irc exception

2 个回答

0

你的错误处理里出现了递归

def login():
    #print('login')
    # Bind the socket
    try:
        s.connect((HOST, PORT))
        # Send login info
        s.send(bytes('NICK %s\r\n' % NICK, 'UTF-8'))
        s.send(bytes('USER %s %s bla :%s\r\n' % (IDENT, HOST, REALNAME), 'UTF-8'))
        s.send(bytes('JOIN %s\r\n' % CHAN, 'UTF-8'));
        print('Logging in...')
        chatlog('Logging in...')
    except:
        print('LOGIN_ERROR')
        login()

在你的login()函数里,你先是用try来尝试一些操作,然后在except里又调用了login()函数。这意味着如果登录失败,它会一直重复这个过程,形成一个死循环。

1

这段代码:

def login():
    ...
    try:
        ...
    except:
        ...
        login()  #  <===

是通过递归的方式调用自己;如果登录失败的次数太多,可能会因为栈的大小限制(这个限制可能和你用的平台有关)而导致栈溢出。

另外,你可以参考这个链接:在Python脚本中设置栈大小

不过我通常会避免使用递归,而是选择循环,除非我事先知道递归的深度不会超过大约100次:

while True:
    try:
        do_login()
    except:  # NOTE: USE A SPECIFIC EXCEPTION CLASS HERE, BTW
        continue
    else:
        break

撰写回答