it-swarm-ko.tech

java.net.SocketException : 연결 재설정

소켓에서 읽으려고 할 때 다음과 같은 오류가 발생합니다. 그 InputStream에 대해 readInt()을하고 있는데이 오류가 나타납니다. 문서를 숙고하면 연결의 클라이언트 부분이 연결을 종료했음을 알 수 있습니다. 이 시나리오에서는 서버입니다.

클라이언트 로그 파일에 대한 액세스 권한이 있으며 연결을 닫지 않고 사실 로그 파일에서 연결을 닫을 것을 제안합니다. 왜 이런 일이 일어나는 지 아무도 모른다. 무엇을 확인할 것인가? 아마도 임계 값에 도달 한 로컬 리소스가있을 때 이것이 발생합니까?


나는 다음 줄을 가지고 있음을 주목한다.

socket.setSoTimeout(10000);

readInt() 직전. 이것에 대한 이유가 있습니다 (긴 이야기). 그러나 단지 호기심이 있다면, 이것이 지시 된 오류로 이어질 수있는 상황이 있습니까? 서버가 IDE에서 실행 중이고 IDE이 중단 점에 고정 된 상태로 있으며 IDE에서 내 자신의 로그에 정확한 오류가 나타나기 시작했습니다.

어쨌든, 그냥 언급, 잘하면 붉은 청어 아닙니다. :-(

101
Darryl

몇 가지 가능한 원인이 있습니다.

  1. 다른 쪽 끝은 의도적으로 연결을 재설정했습니다. 여기서 설명하지 않겠습니다. 응용 소프트웨어가이를 수행하는 것은 드물지만 일반적으로 잘못되었지만 상용 소프트웨어는 알 수 없습니다.

  2. 더 일반적으로 다른 쪽 끝이 이미 정상적으로 닫힌 연결에 쓰는 것이 원인입니다. 즉, 응용 프로그램 프로토콜 오류입니다.

  3. 또한 소켓 수신 버퍼에 읽지 않은 데이터가있을 때 소켓을 닫음으로써 발생할 수 있습니다.

  4. Windows에서 '연결 리셋'과 다른 '소프트웨어 연결 중단이 발생했습니다'는 네트워크 문제로 인해 발생합니다. 이에 대한 Microsoft 기술 자료 문서가 있습니다.

100
user207421

연결 재설정은 단순히 TCP RST가 수신되었음을 의미합니다. 이것은 상대방이 처리 할 수없는 데이터를 수신 할 때 발생하며 그 이유는 여러 가지가있을 수 있습니다.

가장 간단한 방법은 소켓을 닫은 다음 출력 스트림에 더 많은 데이터를 쓸 때입니다. 소켓을 닫음으로써 상대방에게 대화가 끝났다고 말했고 연결 상태는 잊어 버릴 수 있습니다. 어쨌든 스트림에서 더 많은 데이터를 전송하면 피어는 RST로이 스트림을 거부하여 청취하고 있지 않음을 알려줍니다.

다른 경우에, 중간에 방화벽이나 원격 호스트 자체가 TCP 연결을 "잊어 버릴"수 있습니다. 이는 오랜 시간 동안 데이터를 보내지 않으면 (2 시간은 일반적인 시간 초과) 또는 피어가 재부팅되어 활성 연결에 대한 정보가 유실 된 경우에 발생할 수 있습니다. 이러한 중단 된 연결 중 하나에서 데이터를 보내면 RST도 발생합니다.


추가 정보에 대한 응답으로 업데이트 :

SocketTimeoutException 처리에 대해 자세히 살펴보십시오. 이 예외는, 소켓 조작으로 블록되고있는 동안 구성된 타임 아웃을 넘으면 발생합니다. 이 예외가 throw 될 때 소켓 자체의 상태는 변경되지 않지만 예외 처리기가 소켓을 닫고 소켓에 쓰기를 시도하면 연결 재설정 상태가됩니다. setSoTimeout()은 다른 스레드에서 소켓을 닫는 것과 같은 더러운 작업을하지 않고 영원히 차단할 수있는 read() 작업을 중단 할 수있는 깨끗한 방법을 제공합니다.

41
erickson

이런 이상한 문제가 생길 때마다 나는 WireShark 와 같은 도구로 앉아서 앞뒤로 전달되는 원시 데이터를 살펴 본다. 상황이 끊어진 곳에서 놀랄 수도 있고, 시도하고 읽을 때만 통보 할 수 있습니다.

13
GEOCHET

당혹 스럽지만,이 문제가 생겼을 때 모든 데이터를 읽기 전에 연결을 끊는 것이 실수였습니다. 작은 문자열이 반환되는 경우에는 효과가 있었지만 종료하기 전에 전체 응답이 버퍼링 된 것이 원인 일 수 있습니다.

반환되는 텍스트의 양이 길어지면 버퍼가 더 많이 반환되기 때문에 예외가 throw됩니다.

이 감독을 점검 할 수 있습니다. URL 열기는 파일과 같으므로 완전히 읽은 후에는 연결을 해제해야합니다 (연결을 해제하십시오).

8
Scott S

아주 자세하게 전체 추적을 검사해야합니다.

나는 서버 소켓 어플리케이션을 가지고 있고 Java.net.SocketException: Connection reset 케이스를 고쳤다.

제 경우에는 어떤 이유로 인해 연결이 닫혀있는 clientSocket Socket 객체를 읽는 중 발생합니다. (네트워크 손실, 방화벽 또는 응용 프로그램 충돌 또는 의도 된 종료)

사실이 소켓 객체를 읽는 동안 오류가 발생하면 연결을 다시 설정하고있었습니다.

Socket clientSocket = ServerSocket.accept();
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int readed = is.read(); // WHERE ERROR STARTS !!!

클라이언트가 내 ServerSocket에 연결하고 is.read() 자체를 재귀 적으로 호출하지 않고 연결을 닫는 경우 흥미로운 점은 for my Java Socket입니다.이 소켓에서 읽기 위해 무한 루프가 발생했기 때문에 닫힌 연결에서 읽으려고합니다. 읽기 작업에 아래와 같은 것을 사용하면;

while(true)
{
  Receive();
}

그런 다음 아래와 같이 stackTrace를 얻습니다.

Java.net.SocketException: Socket is closed
    at Java.net.ServerSocket.accept(ServerSocket.Java:494)

내가 한 것은 ServerSocket을 닫고 연결을 갱신하고 더 많은 클라이언트 연결을 기다리는 것입니다.

String Receive() throws Exception
{
try {                   
            int readed = is.read();
           ....
}catch(Exception e)
{
        tryReConnect();
        logit(); //etc
}


//...
}

이렇게하면 알 수없는 클라이언트 소켓 손실에 대한 연결이 다시 설정됩니다.

private void tryReConnect()
        {
            try
            {
                ServerSocket.close();
                //empty my old lost connection and let it get by garbage col. immediately 
                clientSocket=null;
                System.gc();
                //Wait a new client Socket connection and address this to my local variable
                clientSocket= ServerSocket.accept(); // Waiting for another Connection
                System.out.println("Connection established...");
            }catch (Exception e) {
                String message="ReConnect not successful "+e.getMessage();
                logit();//etc...
            }
        }

나는 당신이 아래 그림에서 볼 수 있듯이 모든 것이 옳은 것처럼 보이기 때문에 try and catch없이 연결이 끊어 졌는지 여부를 이해할 수 없기 때문에 다른 방법을 찾을 수 없습니다. 내가 계속 Connection reset을 얻는 동안 나는이 스냅 샷을 얻었다.

enter image description here

7
Davut Gürbüz

나는 같은 오류가 있었다. 지금 문제에 대한 해결책을 찾았습니다. 문제는 서버가 스트림을 읽기 전에 클라이언트 프로그램이 끝났습니다.

5
kml_ckr

Java로 작성된 SOA 시스템에서이 문제가 발생했습니다. 다른 물리적 시스템에서 클라이언트와 서버를 모두 실행하고 있었고 오랫동안 정상적으로 작동했지만 클라이언트 로그에 해당 연결 재설정이 나타 났으며 서버 로그에는 이상한 점이 없었습니다. 클라이언트와 서버를 다시 시작해도 문제가 해결되지 않았습니다. 마지막으로 우리는 서버 측의 힙이 다소 꽉 찼기 때문에 JVM에서 사용할 수있는 메모리를 증가 시켰습니다 : 문제가 해결되었습니다! 로그에 OutOfMemoryError가 없다는 사실을 기억하십시오 : 메모리가 부족하고 소진되지 않았습니다.

4
Pino

또한 SSH를 통해 서버에서 명령을 보내려는 Java 프로그램에서이 문제가 발생했습니다. 문제는 Java 코드를 실행하는 시스템에서 발생했습니다. 원격 서버에 연결할 수있는 권한이 없습니다. write () 메서드가 제대로 작동했지만 read () 메서드가 Java.net.SocketException : Connection reset을 throw했습니다. 원격 서버의 알려진 키에 클라이언트 SSH 키를 추가하여이 문제를 해결했습니다.

1
pmartin8

서버의 Java 버전을 확인하십시오. 내 Weblogic 10.3.6이 TLSv1에있는 JDK 1.7.0_75에 있었기 때문에 발생했습니다. 내가 소비하려고했던 나머지 엔드 포인트는 TLSv1.2 이하의 모든 것을 종료했습니다.

기본적으로 Weblogic은 가장 강력한 공유 프로토콜을 협상하려고했습니다. 자세한 내용은 여기를 참조하십시오 : HTTPS 연결을위한 https.protocols 시스템 속성 설정 문제 .

지원되는 TLS를 식별하기 위해 자세한 SSL 로깅을 추가했습니다. 이는 TLSv1이 핸드 셰이크에 사용되고 있음을 나타냅니다.
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

이 기능을 JDK8 호환 제품으로 푸시하여이 문제를 해결했습니다. JDK8의 기본값은 TLSv1.2입니다. JDK7로 제한된 사용자의 경우 TLSv1.2로 업그레이드하여 Java 7에 대한 해결 방법도 성공적으로 테스트했습니다. 이 답변을 사용했습니다 : Java 7에서 TLS 1.2를 활성화하는 방법

0
behold