처리 중인 요청(또는 응답)을 사용자가 기다리지 않고 '새로고침(또는 종료, 연속 클릭)' 을 자주 실행하게 되면 소켓이 끊어져서 발생한다.
예를 들면 다음과 같은 상황이다.
웹브라우저에서 서버에 연결 시도(소켓 사용) -> accept된 socket을 HttpThread에 넘기고 -> ThreadPool에서 조건에 맞으면 해당 HttpThread를 기동
여기서 HttpThread가 일을 다 할 때까지 재요청을 하지 않으면 문제가 되지 않으나, HttpThread가 완료되기전 재요청을 하면 문제가 된다.
처음 요청때 생성된 Socket의 자원을 httpThread.run() 에서 사용하려고 하는 중에, 두번째 요청이 들어와 첫번째 요청의 Socket이 끊어져버리기 때문이다.
java.io.IOException: Broken pipe
receiver가 송신 받은 데이터를 제때 처리하지 못하는 상황일 때
네트워크가 느리거나 서버의 CPU가 max인 경우 등 일 때 sender가 계속 보내는 경우
2개의 소켓상의 통신에서 소켓을 담당하던 프로세서가 갑작스런 이상으로 종료가 된 상황일 때
상대 소켓은 이를 알지 못하고 데이터를 전송하려하면 문제가 발생된다.
예를 들면 다음과 같은 상황이다.
클라이언트에서 요청을 했는데 서버에서 작업을 완료하여 클라이언트로 결과를 넘겨주기 전에 네트워크가 끊김, 클라이언트가 정지 버튼을 누름, 브라우저를 종료, 다른화면으로 이동 등 최초 요청한 정보가 사라졌기 때문에 서버 측에서 작업 결과를 전달할 곳이 없어서 발생한다.
해결 방법
Request(요청) 후 Response(응답) 기다리기
클라이언트는 계속 해서 데이터를 보내지않고, 하나의 레코드를 보낸 뒤 서버에서 정상적으로 수신되었다는 응답을 받게한다. (대신 속도가 좀 느려진다.)
Exception 무시
Client 가 비정상적인 종료를 했을때 Broken pipe Signal이 발생하고 Client의 종료를 서버에서 제어가 불가능 하므로 이 Exception을 무시하는 방법
중복 요청 막기
클라이언트에서 연속적은 버튼 클릭을 방지하거나 Exception 처리 부분에서 오류를 뱉지 않게한다.
예를 들면 다음과 같은 상황이다.
웹브라우저에서 서버에 연결 시도(소켓 사용) -> accept된 socket을 HttpThread에 넘기고 -> ThreadPool에서 조건에 맞으면 해당 HttpThread를 기동
여기서 HttpThread가 일을 다 할 때까지 재요청을 하지 않으면 문제가 되지 않으나, HttpThread가 완료되기전 재요청을 하면 문제가 된다. 처음 요청때 생성된 Socket의 자원을
httpThread.run()
에서 사용하려고 하는 중에, 두번째 요청이 들어와 첫번째 요청의Socket
이 끊어져버리기 때문이다.예를 들면 다음과 같은 상황이다.
클라이언트에서 요청을 했는데 서버에서 작업을 완료하여 클라이언트로 결과를 넘겨주기 전에 네트워크가 끊김, 클라이언트가 정지 버튼을 누름, 브라우저를 종료, 다른화면으로 이동 등 최초 요청한 정보가 사라졌기 때문에 서버 측에서 작업 결과를 전달할 곳이 없어서 발생한다.