나는 이것에 대해 몇 가지 SE 질문이 있다는 것을 알고 있으며,이 시점에 오기 전에 중요한 질문을 많이 읽습니다.
"서버 측 TIME_WAIT
"이란 서버 측에서 close ()가 시작된 서버 측 소켓 쌍의 상태를 의미합니다.
나는 종종 나에게 모순되는 이러한 진술을 본다.
- 서버 측은
TIME_WAIT
무해합니다 - 클라이언트가 close ()를 시작하도록 클라이언트에 네트워크 응용 프로그램을 설계해야합니다.
TIME_WAIT
이 모순을 찾는 이유 TIME_WAIT
는 클라이언트에서 문제가 될 수 있기 때문 입니다. 클라이언트는 사용 가능한 포트가 부족할 수 있으므로 본질적으로 위의 TIME_WAIT
문제는 클라이언트 측으로 문제 를 옮기는 것이 좋습니다 . 문제가 아닌 서버 측.
클라이언트 측은 TIME_WAIT
물론 제한된 수의 유스 케이스에만 문제가됩니다. 대부분의 클라이언트-서버 솔루션에는 하나의 서버와 많은 클라이언트가 포함되며, 클라이언트는 일반적으로 문제가 발생하기에 충분한 양의 연결을 처리하지 않으며, "그렇게해도" "잘못"하는 여러 가지 권장 사항이 있습니다 ( 반대로 SO_LINGER
0 시간 제한, 또는) tcp_tw의 sysctls와 전투 클라이언트 측 간섭 TIME_WAIT
너무 빨리 너무 많은 연결을 만들어 피함으로써. 그러나 다음과 같은 응용 프로그램 클래스와 같이 항상 실현 가능한 것은 아닙니다.
- 모니터링 시스템
- 부하 발생기
- 프록시
다른 한편으로, 나는 서버 측 TIME_WAIT
이 전혀 도움이되는 방법조차 이해하지 못합니다 . 그 이유 TIME_WAIT
는 더 이상 존재 TCP
하지 않는 스트림에 오래된 조각을 주입 하지 못하기 때문입니다. 클라이언트 측 TIME_WAIT
의 ip:port
경우이 오래된 연결이 가질 수 있는 것과 동일한 쌍 (사용 된 쌍이에 의해 잠김 TIME_WAIT
) 으로 연결을 작성하는 것을 불가능하게함으로써 달성됩니다 . 그러나 서버 측의 경우 로컬 주소에 허용 포트가 있고 항상 동일하므로 서버를 막을 수 없으므로 서버는 (AFAIK, 경험적 증거 만 있음) 단순히 연결을 거부 할 수 없습니다. 들어오는 피어는 소켓 테이블에 이미 존재하는 것과 동일한 주소 쌍을 만듭니다.
서버 측 TIME-WAIT가 무시되는 것을 보여주는 프로그램을 작성했습니다. 또한 테스트는 127.0.0.1에서 수행되었으므로 커널에는 서버 쪽인지 클라이언트 쪽인지를 알려주는 특수 비트가 있어야합니다 (그렇지 않으면 튜플이 동일하기 때문에).
출처 : http://pastebin.com/5PWjkjEf , 기본 넷 구성 Fedora 22에서 테스트되었습니다.
$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp TIME-WAIT 0 0 127.0.0.1:44400 127.0.0.1:44401
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address
따라서 서버 측의 TIME_WAIT
경우 정확히 동일한 포트 쌍의 연결을 즉시 성공적으로 다시 설정하고 클라이언트 측의 TIME-WAIT
경우 두 번째 반복에서 connect()
올바르게 실패 할 수 있습니다
요약하면 문제는 두 가지입니다.
- 서버 측은
TIME_WAIT
실제로 아무 작업도하지 않으며,RFC
필요로 하므로 그대로 남아 있습니까? - 서버
TIME_WAIT
가 쓸모 없기 때문에 클라이언트가 close ()를 시작하도록 권장하는 이유 입니까?
TIME_WAIT
합니다.