코드 예제: Java Socket에서 타임아웃과 재시도 로직을 통한 안정적인 요청/응답 구현
1. 소켓 설정 및 타임아웃 적용
Java의 Socket
클래스에는 연결 타임아웃과 리드 타임아웃을 설정할 수 있습니다. 연결 타임아웃을 설정하여 서버 응답 지연 시 자동으로 연결을 해제하고, 재시도 로직을 통해 일정 횟수까지 다시 연결을 시도할 수 있습니다.
import java.io.*; import java.net.Socket; import java.net.SocketTimeoutException; public class SocketClient { private final String host; private final int port; private final int maxRetries = 3; // 최대 재시도 횟수 private final int connectionTimeout = 5000; // 연결 타임아웃 (5초) private final int readTimeout = 5000; // 리드 타임아웃 (5초) public SocketClient(String host, int port) { this.host = host; this.port = port; } public String sendRequest(String message) { int retries = 0; while (retries < maxRetries) { try (Socket socket = new Socket()) { // 소켓 타임아웃 설정 socket.connect(new java.net.InetSocketAddress(host, port), connectionTimeout); socket.setSoTimeout(readTimeout); // 요청 데이터 전송 OutputStream output = socket.getOutputStream(); PrintWriter writer = new PrintWriter(output, true); writer.println(message); // 응답 데이터 수신 InputStream input = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); return reader.readLine(); // 응답 메시지 반환 } catch (SocketTimeoutException e) { System.out.println("Timeout occurred. Retrying... (" + (retries + 1) + "/" + maxRetries + ")"); retries++; } catch (IOException e) { System.out.println("Connection error: " + e.getMessage()); retries++; } // 재시도 전 대기 (1초) try { Thread.sleep(1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new RuntimeException("Thread interrupted during retry delay", ie); } } // 최대 재시도 횟수를 초과할 경우 기본 응답 반환 return "Service unavailable after multiple retries"; } public static void main(String[] args) { SocketClient client = new SocketClient("localhost", 8080); String response = client.sendRequest("Hello, Server!"); System.out.println("Server response: " + response); } }
코드 설명
- 타임아웃 설정:
socket.connect(new java.net.InetSocketAddress(host, port), connectionTimeout)
에서 연결 타임아웃을 설정하며,socket.setSoTimeout(readTimeout)
으로 데이터 수신 시의 타임아웃을 설정합니다. 타임아웃이 초과되면SocketTimeoutException
이 발생합니다. - 재시도 로직: 요청 실패 시
maxRetries
까지 재시도하며, 실패할 때마다 1초 대기합니다. 네트워크 불안정 상태에서 재시도하여 정상 응답을 받을 가능성을 높입니다. - 방어 로직: 재시도 횟수를 초과하거나 연결 오류가 발생할 경우
"Service unavailable after multiple retries"
라는 기본 응답을 반환합니다.
이 코드를 통한 안정적인 소켓 요청/응답의 장점
이 소켓 클라이언트는 서버 연결 시 응답을 기다리면서 발생할 수 있는 지연 문제에 대해 타임아웃과 재시도 로직을 통해 안정성을 보장합니다. 이 구조는 실시간 통신 환경에서도 네트워크 부하에 대응할 수 있도록 설계되어, 클라이언트와 서버 간의 지속적인 통신을 유지하는 데 매우 유용합니다.