2011-05-03 6 views
30

별도의 호스트에서 다른 Python 응용 프로그램과 통신하기 위해 간단한 TCP 소켓을 여는 Python 응용 프로그램이 있습니다. 때로는 프로그램이 오류를 일으키거나 직접 죽일 것이고, 어느 경우 든 알 수없는 시간 동안 소켓이 열린 채로 남아있을 수 있습니다.죽은 프로그램에 의해 열려있는 소켓을 닫는 방법?

내가이 오류는 프로그램 실행으로 이동 다음 시간 :

socket.error: [Errno 98] Address already in use 

지금 프로그램이 항상 동일한 포트를 사용하려고를, 그래서 여전히 열려있는 것처럼 나타납니다. 프로그램을 백그라운드에서 실행하지 않고 내 주소가 아직 사용 중인지 확인하고 확신합니다.

그래, 내 프로그램이 즉시 다시 사용할 수 있도록 어떻게 수동으로 (또는 다른 방법으로) 소켓/주소를 닫을 수 있습니까?

업데이트 나는 socket(7) 페이지를 체크 아웃 SO_REUSEADDR 보았다 마이크의 답변에 따라

:

SO_REUSEADDR 
    Indicates that the rules used in validating addresses supplied in a bind(2) call should 
    allow reuse of local addresses. For AF_INET sockets this means that a socket may bind, 
    except when there is an active listening socket bound to the address. When the listen‐ 
    ing socket is bound to INADDR_ANY with a specific port then it is not possible to bind 
    to this port for any local address. Argument is an integer boolean flag. 
+0

이것을 SO로 이동하는 것에 반대 하시겠습니까? 그것은 완전히 프로그래밍 문제가되어 결국 어쩌면 더 이해할 수 있습니다. –

+0

소켓을 닫으려는 리눅스 명령을 생각하고 있었기 때문에 나는이 글을 게시하지 않았습니다. 프로그래밍 자료에 동의합니다. 제목이 파이썬 프로그램임을 반영하도록 변경 될 수 있습니다. –

+0

@ Mr. Shickadance가 마이 그 레이션 된 경우 제목이 필요하다고 생각하면 제목을 다시 말해야합니다. – xenoterracide

답변

31

서버의에 socket.SO_REUSEADDR를 설정해야합니다 ... 당신의 소켓이 s이라는 가정 소켓을 인터페이스에 바인딩하기 전에 연결하면 ... 즉시 TCP 서버를 다시 시작할 수 있습니다 ...

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.bind((ADDR, PORT)) 
+0

나는' setsockopt', 그리고 나는 그것을 시도했지만 여전히 운이 없다. 더 많은 테스트를 마치면 다시보고하겠습니다. –

+0

@ Mr. Shickadance, 예, setsockopt()입니다. ... 제가 잘못 입력했습니다. –

+0

제가 잘못해서 문제가 해결되었습니다. 그래서 더 많은 테스트를 언급했습니다! 테스트를 실행하기 전에 새 코드를 수정하지 않았습니다 (잊어 버린 것인지 확실하지 않음). 감사! –

10

네트워킹을 위해 Twisted를 사용해 볼 수도 있습니다. 마이크는 정확한 저수준 대답 인 SO_REUSEADDR을 주었지만 Windows에서 설정하는 것이 좋지 않다고 언급하지 않았습니다. 이것은 Twisted가 자동으로 처리하는 일종의 것입니다. 소켓 모듈을 직접 사용할 때주의해야하지만, Twisted와 같은 상위 레벨 라이브러리를 사용하면 잊어 버릴 수있는 지루하고 낮은 수준의 세부 사항에 대한 많은 예제가 많이 있습니다.

+2

'이것은 Windows에서 설정할 수있는 아주 좋은 옵션이 아닙니다'. 왜 안돼? – EJP

+5

Windows에서 REUSEADDR을 사용하면 프로세스가 ** 아직 실행중인 다른 프로세스에서 수신 대기 포트를 인계받을 수 있습니다. –

+1

이것은 unix.stackexchange.com에서 마이그레이션되었으므로 Windows는 큰 관심사가 아닙니다. 어쨌든 좋은 포인트. + 1 –

2

소켓, 연결 및 포트를 혼동스럽게합니다. 소켓은 5-tuples {protocol, local-ip, local-port, remote-ip, remote-port}의 연결 종점입니다. 죽은 프로그램의 소켓은 OS에 의해 닫혀 있고 연결과는 다릅니다. 연결의 유일한 유물은 피어의 소켓과 피어 호스트의 해당 포트입니다. 따라서 실제로 묻고 싶은 것은 로컬 포트를 재사용하는 방법입니다. 그 대답은 다른 대답에 따라 SO_REUSEADDR입니다.

관련 문제