1. 소개

이 빠른 사용방법(예제)에서는 예제를 통해 SocketException 의 원인을 알아 봅니다 .

물론 예외를 처리하는 방법에 대해서도 설명합니다.

2. SocketException의 원인

SocketException 의 가장 일반적인 원인은 닫힌 소켓 연결 에서 데이터를 쓰거나 읽는 것 입니다. 또 다른 원인은 소켓 버퍼의 모든 데이터를 읽기 전에 연결을 닫는 것입니다.

몇 가지 일반적인 근본적인 이유를 자세히 살펴 보겠습니다.

2.1. 느린 네트워크

잘못된 네트워크 연결이 근본적인 문제 일 수 있습니다. 소켓 연결 제한 시간을 더 높게 설정하면 느린 연결에 대한 SocketException 비율이 감소 할 수 있습니다 .

socket.setSoTimeout(30000); // timeout set to 30,000 ms

2.2. 방화벽 개입

네트워크 방화벽은 소켓 연결을 닫을 수 있습니다. 방화벽에 액세스 할 수있는 경우 방화벽을 끄고 문제가 해결되는지 확인할 수 있습니다.

그렇지 않으면 Wireshark 와 같은 네트워크 모니터링 도구를 사용하여 방화벽 활동을 확인할 수 있습니다.

2.3. 긴 유휴 연결

유휴 연결은 다른 쪽 끝에서 잊어 버릴 수 있습니다 (자원 절약). 오랫동안 연결을 사용해야하는 경우 유휴 상태를 방지하기 위해 하트 비트 메시지보낼 수 있습니다 .

2.4. 응용 프로그램 오류

마지막으로 SocketException 은 코드의 실수 나 버그로 인해 발생할 수 있습니다.

이를 증명하기 위해 포트 6699에서 서버를 시작해 보겠습니다.

SocketServer server = new SocketServer();
server.start(6699);

서버가 시작되면 클라이언트의 메시지를 기다립니다.

serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String msg = in.readLine();

정보를 받으면 응답하고 연결을 닫습니다.

out.println("hi");
in.close();
out.close();
clientSocket.close();
serverSocket.close();

따라서 클라이언트가 서버에 연결하여 "hi"를 전송한다고 가정 해 보겠습니다.

SocketClient client = new SocketClient();
client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi");

여태까지는 그런대로 잘됐다.

그러나 클라이언트가 다른 메시지를 보내는 경우 :

client.sendMessage("hi again");

클라이언트는 연결이 중단 된 후 서버에 "hi again"보내므로 SocketException 이 발생합니다.

3. SocketException 처리 

SocketException을 처리하는 것은 매우 쉽고 간단합니다. 확인 된 다른 예외와 마찬가지로 예외를 throw하거나 try-catch 블록으로 둘러싸 야합니다.

예제에서 예외를 처리해 보겠습니다.

try {
    client.sendMessage("hi");
    client.sendMessage("hi again");
} catch (SocketException e) {
    client.stopConnection();
}

여기서는  예외가 발생한 후 클라이언트 연결을 닫았습니다 . 연결이 이미 종료 되었기 때문에 재 시도가 작동하지 않습니다. 대신 새 연결을 시작해야합니다.

client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi again");

4. 결론

이 기사에서는 SocketException의 원인 과 처리 방법을 살펴 보았습니다 .

항상 그렇듯이 코드는 Github에서 사용할 수 있습니다 .