답변:
/etc/init.d/networking restart
자세히 설명하겠습니다. TCP (Transmission Control Protocol)는 두 개의 엔드 포인트 (프로그램) 사이에서 양방향의 순서가 있고 신뢰할 수있는 데이터 전송 프로토콜이되도록 설계되었습니다. 이와 관련하여 신뢰할 수있는 용어는 패킷이 중간에 손실 될 경우 패킷을 재전송한다는 것을 의미합니다. TCP는 피어로부터 수신 한 단일 또는 일정 범위의 패킷에 대해 ACK (Acknowledgement) 패킷을 다시 전송하여 안정성을 보장합니다.
이것은 종료 요청 / 응답과 같은 제어 신호에 대해서도 동일합니다. RFC 793 은 TIME-WAIT 상태를 다음과 같이 정의합니다.
TIME-WAIT-원격 TCP가 연결 종료 요청에 대한 승인을 수신 할 수 있도록 충분한 시간 동안 대기 중임을 나타냅니다.
다음 TCP 상태 다이어그램을 참조하십시오.
TCP는 양방향 통신 프로토콜이므로 연결이 설정 될 때 클라이언트와 서버간에 차이가 없습니다. 또한 둘 중 하나가 통화를 종료 할 수 있으며, 두 피어는 설정된 TCP 연결을 완전히 종료하기 위해 종료에 동의해야합니다.
첫 번째를 호출하여 종료를 활성 클로저로 호출하고 다른 피어를 패시브 클로저로 호출합시다. 액티브 클로저가 FIN을 보내면 상태는 FIN-WAIT-1이됩니다. 그런 다음 전송 된 FIN에 대한 ACK를 수신하고 상태는 FIN-WAIT-2로 이동합니다. 패시브 클로저에서도 FIN을 수신하면 액티브 클로저는 ACK를 FIN으로 보내고 상태는 TIME-WAIT로 이동합니다. 패시브 클로저가 제 2 FIN에 대한 ACK를 수신하지 못한 경우, FIN 패킷을 재전송 할 것이다.
RFC 793 은 TIME-OUT을 최대 세그먼트 수명의 2 배 또는 2MSL로 설정합니다. 패킷이 인터넷을 돌아 다닐 수있는 최대 시간 인 MSL은 2 분으로 설정되고 2MSL은 4 분입니다. ACK에 대한 ACK가 없기 때문에 액티브 클로저는 TCP / IP 프로토콜을 올바르게 준수하면 수동 송신자가 ACK를 FIN에 대한 ACK를받지 못한 경우를 대비하여 4 분 동안 대기 할 수 있습니다. .
실제로, 누락 된 패킷은 드물고 LAN 또는 단일 시스템 내에서 모두 발생하는 경우에는 매우 드 rare니다.
TIME_WAIT에서 강제로 소켓을 닫는 방법?이라는 질문에 답하기 위해 여전히 원래의 대답을 고수합니다.
/etc/init.d/networking restart
실제로 말하면 WMR에서 언급 한대로 SO_REUSEADDR 옵션을 사용하여 TIME-WAIT 상태를 무시하도록 프로그래밍합니다. SO_REUSEADDR은 정확히 무엇을합니까?
이 소켓 옵션은 커널에이 포트가 사용 중이더라도 (
TIME_WAIT 상태) 계속 진행하여 다시 사용하도록 알려줍니다 . 사용 중이지만 다른 상태 인 경우에도 이미 사용중인 주소 오류가 발생합니다. 서버가 종료 된 다음 포트에서 소켓이 여전히 활성 상태 인 동안 즉시 다시 시작하면 유용합니다. 예기치 않은 데이터가 들어 오면 서버를 혼란스럽게 할 수 있지만 이것이 가능하지만 가능하지는 않습니다.
/etc/init.d/networking
는 플랫폼에 따라 다르므로 (Debian?) 정확한 명령 줄은 다른 시스템에 따라 다를 수 있습니다 (때로는 다소 급진적 임). 나는 다른 의견 제시 자들과 관련이 있으며 이는 관련없는 네트워크 서비스에 대해 심각한 과잉과 명백히 파괴적 인 것 같습니다.
실행중인 특정 프로그램의 소스 코드가 있는지 모르겠지만 setsockopt(2)
소켓이 TIME_WAIT 상태에 있더라도 동일한 로컬 주소에 바인딩 할 수있는 SO_REUSEADDR을 설정할 수 있습니다 ( 소켓이 적극적으로 듣고 있습니다 (참조 socket(7)
).
TIME_WAIT 상태에 대한 자세한 내용은 Unix 소켓 FAQ를 참조하십시오 .
SO_REUSEADDR
은 소켓을 "닫지"않습니다. 이미 열려있는 것을 재사용 할 수 있습니다. 따라서 문제는 여전히 "강제로 소켓을 닫는 방법은 TIME_WAIT
무엇입니까?"입니다.
SO_REUSEADDR
bind()
진행 하겠습니다 ; 그러나 그 소켓을 듣고 싶다면 모두 똑같이 listen()
반환 EADDRINUSE
합니다. 즉,이 답변은 임시 포트를 사용하는 클라이언트 소프트웨어에 도움이 될 수 있지만 서버 소프트웨어의 문제는 해결하지 못합니다.
내가 아는 한 더 나은 신호 처리기를 프로그램에 쓰는 것 외에는 소켓을 강제로 닫을 수있는 방법이 없지만 시간 초과가 걸리는 시간을 제어하는 / proc 파일이 있습니다. 파일은
/proc/sys/net/ipv4/tcp_tw_recycle
다음을 수행하여 시간 초과를 1 초로 설정할 수 있습니다.
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
그러나이 페이지 에는이 변수를 설정할 때 발생할 수있는 안정성 문제에 대한 경고가 포함되어 있습니다.
관련 파일도 있습니다
/proc/sys/net/ipv4/tcp_tw_reuse
TIME_WAIT 소켓을 재사용 할 수 있는지 여부를 제어합니다 (아마 시간 초과없이).
또한 커널 설명서는 '기술 전문가의 조언 / 요청'없이 이러한 값을 변경하지 말 것을 경고합니다. 내가 아니야
포트 49200에 대한 바인딩을 시도한 다음 포트가 이미 사용중인 경우 1 씩 증가하도록 프로그램을 작성해야합니다. 따라서 소스 코드를 제어 할 수있는 경우이 동작을 변경하여 몇 초 동안 기다렸다가 동일한 포트에서 다시 시도하지 않고 증가시킬 수 있습니다.
1
향후 연결 을 위해 작동 하도록 설정 했지만 이미 열려있는 현재 연결은 어떻습니까?
다른 옵션은 시간 종료 0으로 SO_LINGER 옵션을 사용하는 것입니다.이 방법으로 소켓을 닫으면 강제로 닫히고 FIN / ACK 닫기 동작으로 들어 가지 않고 RST를 보냅니다. TIME_WAIT 상태를 피할 수 있으며 일부 용도에 더 적합 할 수 있습니다.
TIME_WAIT는 소켓 프로그래밍 클라이언트 서버 아키텍처에서 가장 일반적인 문제입니다. 주기적으로 시도하는 것이 가장 좋은 해결책입니다. 실시간 응용 프로그램의 경우 서버가 즉시 시작되어야합니다. SO_REUSEADDR 옵션이 있습니다.
TIME_WAIT
서버에서" 바로 건너 뛸 를 대답 대신 질문을 피하기 처음 세 개의 답변.