2010-07-06 4 views
0

이것은 코딩 문제 일 수도 있고 아닐 수도 있습니다. xinetd deamon 문제 일 수도 있습니다. 잘 모르겠습니다.파이썬 xinetd 클라이언트 연결 해제 처리

xinetd를 실행하는 Linux 서버에서 실행되는 python 스크립트가 있습니다. Xinetd는 하나의 머신 만이 서비스에 연결할 수 있기를 원하기 때문에 하나의 인스턴스 만 허용하도록 설정되어 있습니다. 따라서 IP로 제한됩니다.

현재 클라이언트가 xinetd에 연결하면 서비스가 제대로 작동하고 스크립트는 클라이언트 컴퓨터로 출력을 보내기 시작합니다. 그러나 클라이언트의 연결이 끊어지면 (즉, 재부팅으로 인해) 서버에서 프로세스가 여전히 작동하며 클라이언트의 재부팅이 완료되면 클라이언트의 연결 기능이 차단됩니다.

Q : 어떻게 파이썬에서 클라이언트의 연결이 끊어 졌는지 탐지 할 수 있습니까? 아마도 stdout이 더 이상 클라이언트에 의해 읽혀지지 않고 (그리고 나서 스크립트를 종료 할 때) 테스트 할 수 있습니까? 아니면 xinetd에 클라이언트가 연결을 끊었을 때 자식 프로세스가 죽게 만드는 많은 방법이 있습니까?

(내가 RHEL5 리눅스에서 파이썬 2.4.3를 사용하고 있습니다 -. 2.4 솔루션이 필요하지만, 3.1 솔루션은 또한 알고 유용 할 것이다)

답변

2

는 SIGHUP위한 신호 처리기를 추가합니다. (x) inetd는 소켓 연결 해제시 이것을 보냅니다.

+0

감사합니다. 추가 검사에서 나는 실제로 코드의 모든 다른 예외를 잡았고 그래서 sighup은 전달되지 않았다. – Sirex

+0

이걸 파헤쳐서 미안하지만,이 라이브 퍼팅에 막 돌아 왔습니다. 기묘하게도,이 didnt는 그것이 내가 가지고있다라고 생각했던 것에 따라 실제로 일한다. 프로세스는 xinetd가 연결이 끊어졌을 때이 응답에 따라 죽어야한다고 의미하는 신호 1 (kill -1 )이 전송되면 죽습니다. 원래 문제는 클라이언트가 연결될 때 xinetd에 의해 시작된 자식 파이썬 프로세스가 클라이언트 연결이 끊어져도 계속 살아 있다는 것입니다. 그 문제는 여전히 거기에있다 :-( 내 파이썬 프로세스는 표준 출력 (그리고 xinetd 때문에 클라이언트의 화면으로) 출력을 출력한다. xinet의 config prehaps를 변경해야 하는가? – Sirex

0

프로세스로 보낸 신호를 모니터하십시오. 어쩌면 스크립트가 xinet에 의해 보내진 SIGHUP에 응답하지 않고, 신호를 모니터하고 죽게 할 수도 있습니다.

0

당신은 SIGHUP을 얻지 못했지만 최소한 연결에서 입출력을 시도하는 한 SIGPIPE를 얻습니다. 응용 프로그램이 IO를 수행하지 않는 데 오랜 시간을 소비하는 경우 단절이 발생하자마자 SIGPIPE를 확보 할 수 있도록 stdin을 읽는 스레드를 시작할 수 있습니다. 이것은 내 응용 프로그램에 충분히 좋았지 만 xinetd가 준 것 이외의 파이프는 사용하지 않았습니다.

나는 사람들이 SIGHUP에 관해 이야기하는 곳에서 클라이언트 단절을 보았 기 때문에 inetd 파이썬 스크립트를 써서 두 개의 서버 (하나의 inetd와 다른 xinetd)를 테스트했다. 당신은 그것을 보내 신호를 확인하는 데 사용할 수 있습니다. /var/log/test.log에 찾은 내용 만 기록합니다. 아마도 유용 할 것입니다.

#!/usr/bin/python 

import os, signal, sys 

skip = ["SIGKILL", "SIG_DFL", "SIGSTOP", "SIG_IGN", "SIGCLD", "SIGCHLD"] 
name_map = {} 
identifiers = [i for i in dir(signal) if i.startswith("SIG") and not i in skip] 

for i in identifiers: 
    name_map[getattr(signal, i)] = i 

def handler(num, frame): 
    signame = name_map[num] 
    os.system("echo handled %s >> /var/log/test.log" % signame) 

if __name__ == "__main__": 
    for id, name in name_map.iteritems(): 
     signal.signal(id, handler) 

    while True: 
     print sys.stdin.readline() 
     sys.stdout.flush() 
관련 문제