우리는 클라이언트가 특정 시간 후에 연결이 끊기는 문제가 있습니다. 클라이언트 측의 예외는 "Read Timed out"메시지를 보여줍니다. 우리는 자바 애플리케이션에서 소켓 타임 아웃을 사용하지 않기 때문에 (기본값 0을 사용한다), 클라이언트의 타임 아웃은 프록시 또는 라우터 쪽에서 이루어져야한다. IT 부서에서이 문제를 조사하고 있습니다.소켓의 입력 스트림에서 닫기가 너무 오래 걸린다
그러나 연결이 중단되면 클라이언트 응용 프로그램이 소켓을 닫은 다음 서버에 대한 새 연결을 설정합니다. 동일한 클라이언트에서 새 연결을 수신하면 서버는 새 연결을 사용하기 전에 이전 연결에 대한 정리 작업을 시작합니다. 이러한 정리 작업은 서버가 EOS 또는 기타 읽기 예외를 감지하거나 동일한 클라이언트에서 새 연결을 수락하고 어떤 이유로 든 이전 연결이 정리되지 않은 경우에 발생합니다 (이는 서버 오류로 인해 발생합니다 EOS를 검출한다). 정리 작업에는 실제로 여러 로깅, 다양한 라우팅 데이터 구조 지우기 및 입력 및 출력 스트림의 마지막 닫기가 포함됩니다. 이 시점에서 우리는 이전 소켓 블록의 입력 스트림이 15 분 동안 닫히고 시간이 항상 동일하다는 사실을 관찰했습니다. 이해할 수 있듯이, 새로운 연결이 굶기 시작하고 같은 문제가 처음부터 반복적으로 시작되기 때문에 모든 것이 잘못되었습니다.
이제 우리 서버 측의 소켓이 FIN_WAIT_2 또는 TIME_WAIT 상태가 불명확하다고 가정합니다.이 상태에서 소켓은 필요한 ACK를받지 못한 상태로 남아 있습니다 (아마도 누락되었습니다). 그것은 CLOSED 상태에있다. 우리 서버가 처음에는 연결을 끊을 수있는 서버가 아니었지만 고객 측의 프록시 또는 라우터라고 가정합니다.이 프록시 또는 라우터가 시작되어 서버가 닫힌 것처럼 보였을 것입니다. 나는 그 상황을 도울 수있는 서버 측의 SO_LINGER 옵션을 0으로 설정하는 것을 읽었지만 (일반적으로 권장되지는 않지만). 참고 : 우리는 SO_LINGER 옵션으로 지금까지 혼란스러워하지는 않았지만 문제로 인해 그렇게 할 생각입니다.
그 이론이 사실인지 설명해 주시겠습니까? 게다가, 왜 소켓 클로즈 작업을 15 분 정도 걸립니까? 이것은 정상적인 2 * MSL (최대 세그먼트 수명) 기간을 초과합니다. 소켓 지속 시간을 기다리는 시간입니다. 우리는 아마도 SO_LINGER 옵션 (자바의 setSoLinger 메소드)의 값을 0보다 큰 값으로 설정해야할까요? 어떤 경우이든, 클라이언트는 이미 다른 쪽에서 연결을 중단 했으므로 소켓을 닫기 직전에 linger 옵션을 0으로 설정해도 클라이언트 측에서 다른 예외 나 잘못된 상태가 발생하지 않습니다. 게다가, 당신은 우리의 환경에서 떨어지는 패킷을 시뮬레이션 할 수있는 도구가 있습니까?
소켓 만들기 및 정리를 수행하는 코드는 특별한 것이 아닙니다.
Socket socket = new Socket(ipAddress, port);
OutputStream dataOutputStream = new BufferedOutputStream(socket.getOutputStream(), 64000);
InputStream dataInputStream = new BufferedInputStream(socket.getInputStream(), 64000);
스트림 폐쇄 코드 소켓의 입력 스트림 소켓 및 출력 스트림을 닫으면
try {
if (dataInputStream != null) {
LOGGER.info("Going to close input stream....");
dataInputStream.close();
}
} finally {
if (dataOutputStream != null) {
LOGGER.info(".closeReaderWriter()", "Going to close output stream...");
dataOutputStream.close();
}
}
소켓을 인스턴스화하고, 소켓을 닫은 위치에서 코드를 다시 공유 할 수 있습니까? – Rainbolt