PROGRAMING/SOCKET
[Socket] Java 소켓: 타임아웃 설정 및 재시도 방법
Popix
2024. 11. 4. 21:52
코드 예제: 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"라는 기본 응답을 반환합니다.
이 코드를 통한 안정적인 소켓 요청/응답의 장점
이 소켓 클라이언트는 서버 연결 시 응답을 기다리면서 발생할 수 있는 지연 문제에 대해 타임아웃과 재시도 로직을 통해 안정성을 보장합니다. 이 구조는 실시간 통신 환경에서도 네트워크 부하에 대응할 수 있도록 설계되어, 클라이언트와 서버 간의 지속적인 통신을 유지하는 데 매우 유용합니다.