java.net.SocketException 수정하는 방법 : 깨진 파이프?
매개 변수를 게시하기 위해 post 메소드를 사용하여 URL을 호출하기 위해 Apache Commons http 클라이언트를 사용하고 있으며 아래 오류가 거의 발생하지 않습니다.
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at org.apache.commons.httpclient.methods.ByteArrayRequestEntity.writeRequest(ByteArrayRequestEntity.java:90)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
누군가이 예외의 원인과 디버깅 방법을 제안 할 수 있습니까?
이 원인은 다음과 같습니다.
- 가장 일반적으로, 다른 쪽 끝이 이미 닫 혔을 때 연결에 쓰는 것;
- 덜 일반적으로, 피어는 끝에서 이미 보류중인 모든 데이터를 읽지 않고 연결을 닫습니다.
따라서 두 경우 모두 응용 프로그램 프로토콜이 잘못 정의되었거나 구현되었습니다.
여기에 문서화하지는 않지만 연결을 올바르게 닫지 않고 재설정하기 위해 의도적으로 조치를 취하는 피어와 관련된 세 번째 이유가 있습니다.
우리의 경우 앱 서버에서로드 테스트를 수행하는 동안이 문제가 발생했습니다. 이 문제는 JVM에 메모리가 부족하여 추가 메모리를 추가해야한다는 것이 밝혀졌습니다. 문제가 해결되었습니다.
JVM에 사용 가능한 메모리를 늘리거나 해당 오류가 발생하면 메모리 사용량을 모니터하십시오.
SocketException : 끊어진 파이프는 코드에서 연결을 읽거나 쓰는 동안 '다른 쪽'(클라이언트 또는 서버)이 연결을 닫아서 발생합니다.
응용 프로그램 제어 외부의 클라이언트 또는 서버에서 트래픽을 수신하는 클라이언트 / 서버 응용 프로그램에서는 매우 일반적인 예외입니다. 예를 들어 클라이언트는 브라우저입니다. 브라우저가 Ajax 호출을하거나 사용자가 단순히 페이지 나 브라우저를 닫으면 모든 통신이 예기치 않게 중단 될 수 있습니다. 기본적으로, 다른 쪽 끝이 응용 프로그램을 종료 할 때마다이 오류가 표시되며 예상하지 않았습니다.
애플리케이션에서이 예외가 발생하면 IO (입력 / 출력)가 발생하는 코드를 확인하고 try / catch 블록으로 랩하여이 IOException을 포착해야 함을 의미합니다. 이 반 유효한 상황을 어떻게 처리할지 결정하는 것은 사용자의 책임입니다.
귀하의 경우, 여전히 통제권이있는 가장 빠른 장소는 전화입니다. HttpMethodDirector.executeWithRetry
따라서 try / catch 블록으로 전화를 감싸고 귀하가 적합한 방식으로 처리하도록하십시오.
디버그 / 추적 레벨 이외의 다른 곳에서는 SocketException-Broken Pipe 특정 오류를 기록하지 않는 것이 좋습니다. 그렇지 않으면 로그를 채워서 DOS (서비스 거부) 공격의 형태로 사용할 수 있습니다. 이 일반적인 시나리오에 대해 애플리케이션을 시험해보고 강화하십시오.
열려있는 모든 스트림과 연결을 올바르게 닫아야하므로 다음에 urlConnection 객체를 사용하려고하면 오류가 발생하지 않습니다. 예를 들어, 다음 코드 변경으로 오류가 해결되었습니다.
전에:
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write("Some text");
bw.close();
out.close();
후:
OutputStream os = urlConnection.getOutputStream();
OutputStream out = new BufferedOutputStream(os);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write("Some text");
bw.close();
out.close();
os.close(); // This is a must.
FTP 서버를 통해 데이터 다운로드 기능을 구현했으며 해당 다운로드를 다시 시작하는 동안 동일한 예외가 발견되었습니다. 이 예외를 해결하려면 항상 이전 세션에서 연결을 끊고 클라이언트의 새 인스턴스와 서버와의 새 연결을 작성해야합니다. 이와 동일한 접근 방식이 HTTPClient에도 도움이 될 수 있습니다.
배포 된 파일이 올바른 RMI 방법으로 업데이트되지 않았을 수 있습니다. RMI 인터페이스에 업데이트 된 매개 변수 또는 클라이언트에없는 데이터 구조가 업데이트되었는지 확인하십시오. 또는 RMI 클라이언트에 서버 버전과 다른 매개 변수가 없습니다.
이것은 단지 교육받은 추측 일뿐입니다. 서버 응용 프로그램의 클래스 파일을 다시 배포하고 다시 테스트 한 후 "깨진 파이프"문제가 사라졌습니다.
The above answers illustrate the reason for this java.net.SocketException: Broken pipe
: the other end closed the connection. I would like to share experience what happened when I encountered it:
- in a client's request, the
Content-Type
header is mistakenly set larger than request body actually is (in fact there was no body at all) - the bottom service in tomcat socket was waiting for that sized body data (http is on TCP which ensures delivery by encapsulating and ...)
- when 60 seconds expired, tomcat throws time out exception:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.net.SocketTimeoutException: null
- client receives a response with status code 500 because of the timeout exception.
- client close connection (because it receives response).
- tomcat throws
java.net.SocketException: Broken pipe
because client closed it.
Sometimes, tomcat does not throw broken pip exception, because timeout exception close the connection, why such a difference is confusing me too.
The cause is that the remote peer closes its socket (crash for example), so if you try to write data to him for example, you will get this. to solve that, protect read/write to socket operations between (try catch), then manage the lose connection case into the catch (renew connection, stop program, ...etc):
try {
/* your code */
} catch (SocketException e) {
e.printStackTrace();
/* insert your failure processings here */
}
JavaDoc:
The maximum queue length for incoming connection indications (a request to connect) is set to 50. If a connection indication arrives when the queue is full, the connection is refused.
You should increase "backlog" parameter of your ServerSocket, for example
int backlogSize = 50 ;
new ServerSocket(port, backlogSize);
참고URL : https://stackoverflow.com/questions/2309561/how-to-fix-java-net-socketexception-broken-pipe
'IT' 카테고리의 다른 글
HsOpenSSL API를 올바르게 사용하여 TLS 서버 구현 (0) | 2020.06.19 |
---|---|
애니메이션 GIF를 PDF에 포함시킬 수 있습니까? (0) | 2020.06.19 |
공분산과 공분산이 값 유형을 지원하지 않는 이유 (0) | 2020.06.19 |
SQL WHERE ID IN (id1, id2,…, idn) (0) | 2020.06.19 |
Java Map이 Collection을 확장하지 않는 이유는 무엇입니까? (0) | 2020.06.19 |