Java.Net.SocketException 수정: Java에서 깨진 파이프 오류
이 자습서는 Java 프로그래밍을 사용하여 java.net.SocketException: Broken pipe
오류를 보여주고 가능한 원인과 해결책을 강조합니다.
오류 설명, 이유 및 해결 방법
오류의 원인을 파악하고 해결책을 찾기 전에 오류를 아는 것이 중요합니다. 따라서 제대로 작동하는 소켓 스트림에 동적 버퍼 크기를 보내야 하는 오류 데모부터 시작하겠습니다.
int myBufferSize = 18 * 1024;
보다 큰 크기의 버퍼를 둘 이상 보내려고 하면 오류가 발생합니다. (표시값입니다).
예제 코드:
byte[] bs = new byte[myBufferSize];
while (...) {
fileInputStream.read(bs);
byte[] bufferToSend = new byte[sizeBuffer];
DataOutputStream dataOutputStream = new DataOutputStream(client.getoutputStream());
dataOutputStream.writeInt(bufferToSend.length);
dataOutputStream.write(bufferToSend);
dataOutputStream.flush();
}
오류 설명:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
깨진 파이프는 무엇을 의미합니까? 끊어진 파이프는 파이프의 다른 쪽에 있는 기계가 종료된 동안 한 기계가 파이프에서 데이터 쓰기/읽기를 시도하고 있음을 의미합니다.
연결이 종료되었으므로 데이터를 전송하려면 새 연결을 설정해야 합니다. 그렇지 않으면 데이터 전송이 중단됩니다.
Java에는 특별히 BrokenPipeException
이 없다는 점을 기억하십시오.
이러한 종류의 오류는 예를 들어 IOException
및 SocketException
과 같은 다른 예외에 시각적으로 래핑됩니다. 우리의 경우 끊어진 파이프는 SocketException
으로 래핑됩니다.
이 문제가 발생하는 이유와 해결 방법은 무엇입니까? 일반적인 원인 중 일부는 다음 섹션에 나와 있습니다.
Java에서 java.net.SocketException: Broken pipe
오류가 발생하는 이유
다음 중 하나가 발생하면 이 오류가 발생할 수 있습니다.
- 이 오류는 여러 클라이언트가 하나의 서버에 연결하고 응답이 완전히 제공/전송되기 전에 여러 클라이언트가 연결을 닫을 때 간헐적으로 발생합니다.
- 대부분의 경우 다른 쪽에서 이미 닫힌 연결에 쓸 때 발생합니다.
- 피어가 전체 데이터를 읽지 않고 연결을 종료할 때도 발생할 수 있습니다. 또 다른 경우에는 피어가 연결을 적절하게 닫는 대신 재설정하기 위해 고의적인 조치를 취합니다.
- 페이지가 완전히 로드되기 전에 사용자가 브라우저를 닫으면 서버에 대한 클라이언트 세션이 예기치 않게 연결 해제됩니다.
- 또는 현재 페이지가 완전히 로드되기 전에 사용자가 다른 페이지로 이동합니다.
- 로드하는 동안 인터넷 연결이 실패할 때도 이 오류가 발생합니다.
- 이 오류의 또 다른 상황은 요청 연결에 대한 연결 시간이 초과된 브라우저가 완료된 경우입니다. 대부분 큰 리소스를 업로드하려고 할 때 발생합니다.
Java에서 java.net.SocketException: Broken pipe
오류를 근절하기 위한 가능한 솔루션
클라이언트-서버 프로그래밍을 수행하는 동안 이 오류를 제거하기 위해 다양한 방법을 사용할 수 있습니다. 개발자에게 알리기 위해 근본 원인을 무시하거나 처리하시겠습니까?
-
일반적으로 서버 응용 프로그램에 대한 이러한 유형의 오류 처리는 우리 서버가 다른 클라이언트의 영향을 받지 않도록 필요합니다. 예, 지원 담당자로서 데이터/응답이 완전히 전송되기 전에 클라이언트의 연결이 이미 끊어졌기 때문에 무시할 수 있습니다.
-
대용량 리소스를 업로드하는 중에 오류가 발생하면 긴 요청 시간 초과로 API를 잘 처리해야 합니다.
-
때때로 포트 스캐너는 연결을 열고 즉시 닫는 방식으로 작업을 수행합니다. 우리 서버는 연결 실패를 처리하도록 프로그래밍되어 있지 않습니다.
이 상황에 대해 코딩하지 않았기 때문입니다. 여기서는
try-catch
를 사용하여 이 상황을 처리해야 합니다. -
깨진 파이프 문제는 코드가 아닌 다른쪽에 있습니다. 아마도 다른 쪽 끝(클라이언트 또는 서버일 수 있음)은 우리의 길이-단어 프로토콜을 이해하지 못할 것입니다.
예를 들어 올바르게 구현하지 않습니다. 이 코드(오류의 데모에서 제공됨)와 유사한 것이 있으면 그렇지 않습니다.
read()
가 반환한 응답을 무시합니다. 또한 버퍼를 채우고 있다고 가정합니다. 그렇게 하도록 지정되어 있지 않고 1바이트만 전송/전송하도록 지정되어 있습니다. -
또 다른 해결책은 입력/출력 예외가 발생한 코드를 확인하고
try-catch
블록으로 래핑하여IOException
을 포착하는 것입니다. 그런 다음 이 반 유효 시나리오를 처리하는 방법을 결정하는 것은 우리에게 달려 있습니다.이 경우는 끊어진 파이프가
IOException
을 감싸는 경우에만 적용된다는 점을 기억하십시오.