시간 웨이트 암살과 SO_Reuseaddr의 차이점은 무엇입니까?
문제
나는 SO_LINGER 소켓 옵션을 사용하여 Linger Time을 0으로 설정하여 의도적으로 Time-Wait 상태를 '암살'하는 것에 대해 읽었습니다. 그 책의 저자는 계속해서 우리는 이것을하지 말아야하며 일반적으로 시간 웨이트 상태를 방해해서는 안된다고 말합니다. 그런 다음 즉시 SO_REUSEADDR 옵션을 사용하여 시간 웨이트 상태를 우회 할 것을 권장합니다.
내 질문은 차이점이 무엇입니까? 두 경우 모두 조기에 시간 웨이트 상태를 종료하고 중복 세그먼트를받을 위험이 있습니다. 왜 하나가 좋고 다른 하나는 나쁜가요?
해결책 2
나는 더 많은 독서를했고 이것은 무슨 일이 일어나는지에 대한 나의 이해입니다 (희망적으로 정확).
SO_REUSEADDR 설정이있는 소켓에서 가까이 호출 할 때 (또는 앱 충돌) 다음 순서가 발생합니다.
- TCP는 보내기 버퍼와 FIN에서 나머지 데이터를 보냅니다.
- Close를 호출하면 나머지 데이터가 성공적으로 전달되었는지 표시없이 즉시 반환됩니다.
- 데이터가 전송 된 경우 피어가 데이터 ACK를 보냅니다.
- 피어는 핀의 ACK를 보내고 자체 지느러미 패킷을 보냅니다.
- 피어의 지느러미는 어 크고 소켓 리소스가 처리됩니다.
- 소켓은 시간 정리에 들어 가지 않습니다.
SO_LINER 시간이 0으로 설정된 소켓을 닫을 때 :
- TCP는 보내기 버퍼의 데이터를 버립니다
- TCP는 RST 패킷을 피어에게 보냅니다
- 소켓 리소스가 처리됩니다.
- 소켓은 시간 정리에 들어 가지 않습니다
따라서 남아를 제로로 설정하는 것은 해킹과 나쁜 스타일이라는 사실을 넘어서 연결의 깨끗한 종료를 거치지 않기 때문에 나쁜 태도입니다.
다른 팁
Time_wait는 절대적으로 정상입니다. 로컬 쪽에서 TCP 핀 후에 발생한 후 원격 위치에서 TCP 핀 ACK가 발생합니다. time_wait에서 당신은 길 잃은 패킷이 로컬 주소에 도착하기를 기다리고 있습니다. 그러나 손실되거나 길 잃은 패킷이있는 경우 Time_wait가 주소를 다시 사용하기 전에 TTL 또는 "LIVE TON LIVE"가 만료되는지 확인하십시오.
당신이 so_reuseaddr을 사용한다면, 당신은 기본적으로 말하고 있습니다. 나는 길 잃은 패킷이 없다고 가정 할 것입니다. 현대적이고 신뢰할 수있는 TCP 네트워크에서 점점 더 가능성이 높습니다. 여전히 가능하지만 가능성은 거의 없습니다.
so_linger를 0으로 설정하면 "연결 종료를 슬래 밍"이라고도하는 비정상적인 닫기를 시작하게됩니다. 여기서 당신은 Time_wait을 존중하지 않고 길 잃은 패킷의 가능성을 무시합니다.
FIN_WAIT_1이 보이면 원격 위치가 핀에 대한 응답으로 TCP FIN ACK를 보내지 않았으므로 문제가 발생할 수 있습니다. 따라서 프로세스가 사망하거나 네트워크 파티션 또는 나쁜 경로로 인해 TCP 핀 ACK가 손실되었습니다.
Close_wait가 보이면 문제가 있습니다. 여기에서 TCP 핀이 주어지면 TCP 핀 ACK를 보내지 않기 때문에 연결이 유출됩니다.
나는 So_reuseaddr을 WildCard Bind ()에 사용하여 다른 프로그램이 이미 연결되어있는 로컬 포트에 사용했습니다. 이 특별한 용도는 동시에 동일한 Addr/Port Combo에서 ()을 듣지 않는 한이 특정 용도는 결코 문제를 일으키지 않을 것입니다.