“소프트웨어가 연결 중단을 일으킨 이유 : 소켓 쓰기 오류”


157

이 스택 추적 스 니펫이 주어지면

원인 : java.net.SocketException : 소프트웨어로 인한 연결 중단 :
 java.net.SocketOutputStream.socketWrite0 (네이티브 메소드)에서 소켓 쓰기 오류

나는 다음과 같은 질문에 대답하려고 노력했다.

  1. 어떤 예외가이 예외를 던지고 있습니까? (JVM? / Tomcat? / 내 코드?)
  2. 이 예외가 발생하는 원인은 무엇입니까?

# 1에 관하여 :

Sun의 JVM 소스에는이 정확한 메시지가 포함되어 있지 않지만 소프트웨어에서 연결 중단을 일으킨 텍스트 : 소켓 쓰기 오류 는 다음과 같은 기본 구현에서 발생 했다고 생각합니다 SocketOutputStream.

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

# 2에 대하여

내 생각에 그것은 전체 응답을 받기 전에 클라이언트가 연결을 종료했을 때 발생합니다 (예 : 요청을 보냈지 만 전체 응답을 받기 전에 닫히거나 종료 / 오프라인 상태)

질문 :

  1. 위의 가정이 맞습니까 (# 1 및 # 2)?
  2. " 서버 측 의 네트워크 오류로 인해 클라이언트에 쓸 수 없습니다"라는 상황에서이를 구별 할 수 있습니까 ? 또는 동일한 오류 메시지가 표시됩니까?
  3. 그리고 가장 중요한 : 위의 내용을 명시한 공식 문서 (예 : Sun)가 있습니까?

이 스택 추적이 소켓 클라이언트의 "결함"이라는 증거가 필요하며 서버가이를 피하기 위해 할 수있는 일은 없습니다. (예외를 잡거나 Sun JVM SocketOutputStream 이외의 것을 사용하는 것을 제외하고는 클라이언트가 종료되었다는 사실을 실제로 피하지는 않습니다)


Firefox로 다운로드를 취소 할 때이 문제가 발생합니다
koppor

Eran 안녕하세요.에 보내기 / 쓰기 ( outs.write(audioBytes);) 하는 동안이 예외가 발생 byte[]합니다 OutputStream. 사용자가 다른 메뉴를 클릭하면 (서버 요청을 보내는) 오디오가 작동하고 재생 중일 때 콘솔에서 동일한 오류가 발생합니다. 이 예외를 무시해도 안전합니까?
Amogh

1
@Amogh-그렇습니다. 기본적으로 답변에서 설명하는 바에 따르면, 이것은 Windows 관련 오류이지만 Linux에서는 다른 단어로 동일한 예외가 발생한다고 가정합니다 ... (내 평신도 용어 이해는 기본적으로 보낼 때 발생한다는 것입니다 소켓을 통해 X와 X가 중간에 연결이 끊어졌지만 그것을 설명하는 가장 정확한 방법은 아니라고 확신합니다)
Eran Medan

1
나에게 이것은 데이터베이스 서버가 다시 시작되고 응용 프로그램이 여전히 이전에 열린 연결을 사용하여 쿼리하려고 할 때 발생했습니다. DBCP 기반 풀링을 사용하고 있는데 왜 이것이 갱신되지 않았는지 잘 모르겠습니다. 그러나 응용 프로그램을 다시 시작하면 문제가 해결되었습니다.
Kshitiz Sharma 2012

답변:


55

이 오류는 데이터 재전송이 실패한 후 WinSock이 설정된 연결을 닫을 때 (수신자가 데이터 스트림 소켓에서 전송 된 데이터를 승인하지 않음)와 같이 로컬 네트워크 시스템이 연결을 중단 할 때 발생할 수 있습니다.

참조 이 MSDN 문서를 . '소프트웨어로 인한 연결 중단'에 대한 일부 정보 도 참조하십시오 .



3
@MatGessel이 기사는 혼란을 반복하고 자체 기사를 추가합니다. WSAECONNABORTED는 Winsock 오류 코드이므로 버클리에 대한 설명이 없을 수도 있습니다. HTTP 서버에 대해 설명 된 상황은 WSAECONNABORTED가 아니라 ECONNRESET을 생성합니다.
Lorne의 후작 22.13.

@ EJP, OutputStream에 (outs.write (audioBytes);) byte []를 보내거나 쓰는 동안이 예외가 발생합니다. 사용자가 다른 메뉴를 클릭하면 (서버 요청을 보내는) 오디오가 작동하고 재생 중일 때 콘솔에서 동일한 오류가 발생합니다. 이 예외를 무시해도 안전합니까?
Amogh

1
@rustyx 여기에 인용 된 세 가지 출처는 모두 ACK 오류로 인해 생성 된 것입니다. 자신의 주장에 대한 출처가있는 경우 인용하십시오.
Lorne의 후작

2
이것은 문제를 더 추구 할 정보를 제공하지 않기 때문에 실제 답변이 아닙니다. 여기서의 대답은 기본적으로 "네트워크에 문제가 발생했습니다"입니다. 추가 로그 및 기타 활동 기록을 통해 근본적인 문제를 정확히 파악할 수있는 방법을 이해하면 도움이 될 것입니다.
Derek Bennett

11

java.net.SocketException만들거나 액세스 할 경우에 에러가 발생했을 경우에 슬로우되는 소켓을 (예 : TCP ). 이 문제는 일반적으로 서버가 연결을 종료하지 않고 (올바르게 닫지 않은 경우) 발생할 수 있으므로 전체 응답을 얻습니다. 대부분의 경우 시간 초과 문제 (예 : 응답 시간이 너무 오래 걸리거나 서버에 요청이 오버로드 됨) 또는 클라이언트가 SYN을 보냈지 만 ACK를받지 못했습니다 (연결 종료 확인) . 시간 초과 문제의 경우 시간 초과 값을 늘릴 수 있습니다.

소켓 예외는 일반적으로 문제에 대한 지정된 세부 메시지와 함께 제공됩니다.

자세한 메시지 예 :

  • 소프트웨어에서 연결 중단이 발생했습니다 : recv 실패.

    오류는 메시지 전송 시도를 나타내며 서버에서 연결을 중단했습니다. 데이터베이스에 연결하는 동안이 문제가 발생하면 호환되지 않는 Connector / J JDBC 드라이버 사용과 관련이있을 수 있습니다 .

    가능한 해결책 : CLASSPATH에 적절한 라이브러리 / 드라이버가 있는지 확인하십시오.

  • 소프트웨어에서 연결 중단이 발생했습니다 : 연결.

    리모컨 연결에 문제가있을 때 발생할 수 있습니다. 예를 들어 바이러스 검사 프로그램이 원격 메일 요청을 거부하기 때문 입니다.

    가능한 해결책 : 연결을 위해 나가는 요청의 포트를 차단하고 있는지 바이러스 검사 서비스를 확인하십시오.

  • 소프트웨어에서 연결 중단이 발생했습니다 : 소켓 쓰기 오류.

    가능한 해결책 : 스트림에 올바른 길이의 바이트를 쓰고 있는지 확인하십시오. 전송중인 내용을 다시 확인하십시오. 이 스레드를 참조하십시오 .

  • 피어에 의한 연결 재설정 : 소켓 쓰기 오류 / 피어에 의한 연결 중단 : 소켓 쓰기 오류

    서버 쪽에서 연결 유지 연결 시간이 초과되었는지 응용 프로그램에서 확인하지 않았습니다.

    가능한 해결책 : 연결에서 읽기 전에 HttpClient가 널이 아닌지 확인하십시오. E13222_01

  • 피어에 의한 연결 재설정

    피어 (서버)가 연결을 종료했습니다.

  • 연결 재설정.

    요청에 의한 요청으로 인해 클라이언트가 연결을 종료했거나 연결이 서버 쪽에서 닫혔습니다.

    참조 : 내 java.net.SocketException의 원인을 무엇 : 연결 재설정?


이 6 점 중 하나만이 실제로 질문에 대한 답을 잘못 제시합니다. 다른 몇 가지도 올바르지 않습니다. 응용 프로그램 '서버 쪽에서 연결 유지 연결이 시간 초과되었는지 여부를 확인할 수 없습니다 .' HttpClient존재 null는 아마도 원인 이 될 수 없습니다 SocketException. 스트림에 올바른 길이를 쓰지 않는 것도 마찬가지입니다.
Lorne의 후작

9

워크 스테이션 / 노트북의 회사 방화벽이 방해를 받으면 연결이 끊어집니다.

예. 같은 컴퓨터에 서버 프로세스와 클라이언트 프로세스가 있습니다. 서버가 모든 인터페이스 (0.0.0.0)에서 수신 대기 중이며 클라이언트가 공용 / 홈 인터페이스 (루프백 인터페이스 127.0.0.1이 아님)에 대한 연결을 시도합니다.

기기의 네트워크 연결이 끊긴 경우 (예 : wifi가 꺼진 경우) 연결이 형성됩니다. 기기가 회사 네트워크 (직접 또는 VPN)에 연결된 경우 연결이 형성됩니다.

그러나 기기가 공용 ​​Wi-Fi (또는 홈 네트워크)에 연결되어 있으면 방화벽이 작동하여 연결이 끊어집니다. 이 상황에서 클라이언트를 루프백 인터페이스에 연결하면 홈 / 공용 인터페이스가 아니라 제대로 작동합니다.

도움이 되었기를 바랍니다.


3
방화벽은 연결을 방지 합니다. 문제는 기존 연결을 재설정하는 것입니다.
Lorne의 후작

4

어떤 구성 요소가 실패했는지 증명하기 위해 wireshark를 사용하여 TCP / IP 통신을 모니터링하고 누가 포트를 실제로 닫고 있는지 확인합니다. 시간 제한도 관련이 있습니다.


아무도 항구를 닫고 있지 않습니다. 운영 체제가 연결을 중단하고 있습니다.
Lorne의 후작

@ EJP 나는 오버로드되고 메모리가 부족할 때 이런 일이 발생하는 것을 보았습니다. 연결을 닫는 것이 OS인지 확실하지 않지만 JVM은 잘못 작동합니다.
Zee

1
@Zee Wireshark에서 FIN으로 표시되는 포트를 닫는 것과 연결을 중단하는 것에는 차이가 있습니다.
Lorne의 후작

2

Tomcat 소스 코드 JVM 소스 를 확인 했습니까 ? 도움이 더 필요할 수 있습니다.

나는 당신의 일반적인 생각이 좋다고 생각합니다. 나는 ConnectException당신이 연결할 수없는 시나리오를 기대할 것 입니다. 위의 내용은 클라이언트 중심의 것 같습니다.


3
예, 확인했습니다. Tomcat의 출처에는 문장의 순열이 포함되어 있지 않습니다. 감사합니다.
Eran Medan

1
그는 Tomcat 소스 JVM 소스를 확인하지 않았습니다 .
Stephen C

또는 JVM 소스를 확인한 경우 모든 소스를 확인하지 않았습니다.
Stephen C

1
@Ehrann-메시지 문자열은 기본 소스에있을 가능성이 높습니다. 그러나 이벤트 로그도 확인해야합니다. 후자는 IMO가 더 유익 할 것입니다.
Stephen C

6
이 메시지 문자열은 실제로 운영 체제에서 제공됩니다.
론 후작

2

간단한 클라이언트 서버 프로그램을 사용하고이 오류가 발생하는 사람은 닫히지 않은 (또는 초기에 닫히는) 입력 또는 출력 스트림의 문제입니다.


2
아닙니다. 소켓 누출이 발생하여 결국 FD 고갈이 발생합니다.
Lorne의 후작

0

나는 같은 문제에 직면했다.
일반적으로 이러한 종류의 오류는 클라이언트가 연결을 닫고 서버가 여전히 해당 클라이언트에 쓰려고하기 때문에 발생합니다.
따라서 서버가 출력 스트림을 완료 할 때까지 클라이언트의 연결이 열려 있는지 확인하십시오.
그리고 한 가지 더, 입력 및 출력 스트림닫는 것을 잊지 마십시오 .

도움이 되었기를 바랍니다.
여전히 문제가 발생하면 여기에서 문제를 간단히 설명하십시오.


3
@BhavinChhatrola 아니요, 오답입니다. 설명 된 상황은 문제의 오류가 아닌 '피어에 의한 연결 재설정'을 생성합니다.
Lorne의 후작

0

SoapUI 클라이언트로 비누 서비스를 테스트하는 동안이 오류가 발생했습니다. 기본적으로 매우 큰 메시지 (> 500kb)를 얻으려고했지만 SoapUI가 시간 초과로 연결을 닫았습니다.

SoapUI에서 다음으로 이동하십시오.

파일-> 기본 설정-소켓 시간 초과 (ms)

... 180000 (3 분)과 같은 큰 값을 넣으면 파일이 실제로 크기 때문에 문제에 대한 완벽한 해결책은 아니지만 최소한 응답이있을 것입니다.


0

다른 클라이언트에서 닫힌 연결

필자의 경우 오류는 다음과 같습니다.

java.net.SocketException: Software caused connection abort: recv failed

H2 데이터베이스에 액세스하는 Java 애플리케이션을 디버깅하는 동안 일식으로 수신되었습니다. 오류의 원인은 처음에 SQuirreL로 데이터베이스를 열어 무결성을 수동으로 확인했다는 것입니다. 플래그를 사용하여 동일한 DB에 여러 연결을 가능하게했습니다 (즉AUTO_SERVER=TRUE )에 있으므로 java에서 DB에 연결하는 데 아무런 문제가 없었습니다.

이 오류는 잠시 후 긴 Java 프로세스 인 경우에 발생했습니다. 리소스를 확보하기 위해 SQuirreL을 닫기로 결정했습니다. SQuirreL이 DB 서버 인스턴스를 "소유"한 것으로 보이고 SQuirreL 연결로 종료 된 것처럼 보입니다.

Java 애플리케이션을 다시 시작해도 오류가 다시 발생하지 않았습니다.

설정

  • 윈도우 7
  • 이클립스 케플러
  • SQuirreL 3.6
  • org.h2.Driver 버전 1.4.192

0

필자의 경우 클라이언트와 서버 측을 개발했지만 예외가 있습니다.

원인 : 오류 마샬링 인수; 중첩 된 예외는 다음과 같습니다. java.net.SocketException : 소프트웨어로 인해 연결이 중단되었습니다 : 소켓 쓰기 오류

클라이언트와 서버의 클래스가 다른 경우 클라이언트에서 서버 클래스 (인터페이스)를 다운로드하지 않고 프로젝트에 동일한 파일을 추가하기 만합니다. 그러나 경로는 정확히 동일해야합니다. 예를 들어, 서버 프로젝트에서 일부 serviceInterface 및 구현을 사용하는 java \ rmi \ services 패키지가 있으며 클라이언트 프로젝트에서 동일한 패키지를 작성해야합니다. 예를 들어 java / rmi / server / services로 변경하면 위의 예외가 발생합니다. 클라이언트와 서버간에 인터페이스 버전이 다른 경우에도 동일한 예외가 발생합니다 (빈 행이 실수로 추가 된 경우에도 ... rmi는 버전을 확인하기 위해 일종의 클래스 해시를 만드는 것 같습니다 ... 모릅니다 ... 도와주세요 ...


-1

내 서버는 2 일 만 에이 예외를 던지고 연결 해제 기능을 다음과 같이 이동하여 해결했습니다.

outputStream.close();
inputStream.close();
Client.close();

리스팅 스레드의 끝. 누군가에게 도움이 될 것입니다.


-1

아래에 설명 된 상황에서 클라이언트 측은 이러한 예외를 발생시킵니다.

서버는 클라이언트 인증서를 인증하도록 요청 받지만 클라이언트는 확장 키 사용이 클라이언트 인증을 지원하지 않는 인증서를 제공하므로 서버는 클라이언트의 인증서를 수락하지 않고 연결을 닫습니다.


이 답변은 잘못되었습니다. 설명하는 경우 SSLException이 발생합니다.
James K. Polk 대통령,

실제로 그것은 현재 질문처럼 SocketException을 던졌습니다. 나는 테스트했습니다
xiaoming

-1

ssl 클라이언트 측은 아래 상황에서 그러한 예외를 던질 것입니다 (테스트했습니다).

서버는 클라이언트 인증서를 인증하도록 요청 받지만 클라이언트는 확장 키 사용이 클라이언트 인증을 지원하지 않는 인증서를 제공합니다.


-3

나머지 API 호출을 조롱하는 동안 wireMock과 동일한 문제에 직면했습니다. 이전에는 다음과 같이 서버를 정의하고있었습니다.

WireMockServer wireMockServer = null;

그러나 아래와 같이 정의해야합니다.

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);

NullPointerException이 문제가 아닌을 일으킬 것 입니다.
Lorne의 후작
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.