[PYTHON] 파이썬에서 깨진 파이프 (SIGPIPE)를 처리하는 방법은 무엇입니까?
PYTHON파이썬에서 깨진 파이프 (SIGPIPE)를 처리하는 방법은 무엇입니까?
필자는 각 클라이언트 연결에 대해 새로운 스레드를 생성하는 간단한 멀티 스레드 게임 서버를 파이썬으로 작성했습니다. 지금은 깨진 파이프 / SIGPIPE 오류로 인해 서버가 중단 될 때가 있습니다. 프로그램이 더 이상 존재하지 않는 클라이언트에게 응답을 보내려고 할 때 일어난다 고 나는 확신한다.
이것을 처리하는 좋은 방법은 무엇입니까? 필자가 선호하는 해결책은 전체 프로그램을 종료하는 대신 클라이언트에 대한 서버 측 연결을 닫고 계속 진행하는 것입니다.
추신 :이 질문 / 답변은 일반적인 방법으로 문제를 다룹니다. 얼마나 구체적으로 해결해야합니까?
해결법
-
==============================
1.try : 문을 읽으십시오.
try : 문을 읽으십시오.
try: # do something except socket.error, e: # A socket error except IOError, e: if e.errno == errno.EPIPE: # EPIPE error else: # Other error
-
==============================
2.표준 소켓 모듈을 사용한다고 가정하면 socket.error : (32, 'Broken pipe') 예외 (IOError가 아닌 다른 제안 사항)를 포착해야합니다. 이것은 원격 측의 연결이 끊어진 소켓으로 보내거나 쓰는 것과 같이 설명 된 경우에 발생합니다.
표준 소켓 모듈을 사용한다고 가정하면 socket.error : (32, 'Broken pipe') 예외 (IOError가 아닌 다른 제안 사항)를 포착해야합니다. 이것은 원격 측의 연결이 끊어진 소켓으로 보내거나 쓰는 것과 같이 설명 된 경우에 발생합니다.
import socket, errno, time # setup socket to listen for incoming connections s = socket.socket() s.bind(('localhost', 1234)) s.listen(1) remote, address = s.accept() print "Got connection from: ", address while 1: try: remote.send("message to peer\n") time.sleep(1) except socket.error, e: if isinstance(e.args, tuple): print "errno is %d" % e[0] if e[0] == errno.EPIPE: # remote peer disconnected print "Detected remote disconnect" else: # determine and handle different error pass else: print "socket error ", e remote.close() break except IOError, e: # Hmmm, Can IOError actually be raised by the socket module? print "Got IOError: ", e break
이 예외는 닫혀진 소켓에 대한 첫 번째 쓰기에서 항상 발생하는 것은 아니며, 일반적으로 두 번째 쓰기 (첫 번째 쓰기에서 작성된 바이트 수가 소켓의 버퍼 크기보다 큰 경우는 제외)입니다. 응용 프로그램이 원격 종료가 이미 연결이 끊어져있을 때 첫 번째 쓰기에서 데이터를 수신했다고 생각할 경우이를 염두에 두어야합니다.
select.select () (또는 poll)를 사용하여이 문제의 발생률을 줄일 수는 있지만 완전히 제거 할 수는 없습니다. 쓰기를 시도하기 전에 피어에서 읽을 준비가 된 데이터를 확인하십시오. select가 피어 소켓에서 읽을 수있는 데이터가 있다고보고하면 socket.recv ()를 사용하여 읽습니다. 이 메소드가 하늘의 캐릭터 라인을 돌려주는 경우, 원격 피어는 접속을 닫습니다. 아직 여기에는 경쟁 조건이 있으므로 예외를 잡아서 처리해야합니다.
Twisted는 이런 종류의 일에 아주 좋습니다. 그러나 이미 꽤 많은 코드를 작성한 것 같습니다.
-
==============================
3.SIGPIPE (비록 내가 EPIPE를 의미 할까?)는 소켓을 셧다운하고 데이터를 보낼 때 소켓에서 발생한다. 간단한 해결책은 데이터를 보내기 전에 소켓을 종료하지 않는 것입니다. 이것은 파이프에서도 발생할 수 있지만, 네트워크 서버이므로 사용자가 경험 한 것처럼 들리지는 않습니다.
SIGPIPE (비록 내가 EPIPE를 의미 할까?)는 소켓을 셧다운하고 데이터를 보낼 때 소켓에서 발생한다. 간단한 해결책은 데이터를 보내기 전에 소켓을 종료하지 않는 것입니다. 이것은 파이프에서도 발생할 수 있지만, 네트워크 서버이므로 사용자가 경험 한 것처럼 들리지는 않습니다.
또한 각 스레드의 일부 최상위 핸들러에서 예외를 잡아 내기위한 반창고를 적용 할 수도 있습니다.
물론 각 클라이언트 연결마다 새 스레드를 생성하는 대신 Twisted를 사용한 경우이 문제가 발생하지 않을 것입니다. 여러 스레드가 동일한 I / O 채널을 처리하는 경우 닫기 및 쓰기 작업의 순서를 올바로 지정하는 것이 매우 어렵습니다 (응용 프로그램에 따라 불가능할 수도 있음).
-
==============================
4.나는 똑같은 질문에 직면 해있다. 하지만 다음에 동일한 코드를 제출하면 작동합니다. 처음으로 그것이 고장 났을 때 :
나는 똑같은 질문에 직면 해있다. 하지만 다음에 동일한 코드를 제출하면 작동합니다. 처음으로 그것이 고장 났을 때 :
$ packet_write_wait: Connection to 10.. port 22: Broken pipe
두 번째로 작동합니다.
[1] Done nohup python -u add_asc_dec.py > add2.log 2>&1
이유는 현재 서버 환경에 관한 것일 수 있습니다.
-
==============================
5.내 대답은 S.Lott 's에 매우 가깝다.
내 대답은 S.Lott 's에 매우 가깝다.
try: # do something except IOError, e: # ooops, check the attributes of e to see precisely what happened. if e.errno != 23: # I don't know how to handle this raise
여기서 "23"은 EPIPE에서 얻은 오류 번호입니다. 이렇게하면 사용 권한 오류 또는 사용자가 갖추고 있지 않은 다른 것을 처리하지 않습니다.
from https://stackoverflow.com/questions/180095/how-to-handle-a-broken-pipe-sigpipe-in-python by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 루핑하는 동안 이전 / 다음 요소에 액세스하는 방법? (0) | 2018.10.10 |
---|---|
[PYTHON] ctypes에 C ++ 클래스를 사용하는 방법? (0) | 2018.10.10 |
[PYTHON] Python 및 Flask로 데이터 스트리밍 (0) | 2018.10.10 |
[PYTHON] Python으로 파일의 마지막 x 줄을 검색하는 가장 효율적인 방법 (0) | 2018.10.10 |
[PYTHON] MAPI를 통해 Python으로 Outlook에서 전자 메일 읽기 (0) | 2018.10.10 |