네트워크 프로그래밍에서 예외는 크게 두 범주로 나뉜다. 연결 자체가 불가능한 경우와, 연결은 시도됐지만 실패하는 경우다. 이번 글에서는 소켓 연결 시 발생하는 대표적인 예외 세 가지를 코드와 함께 정리한다
예제 코드
import java.io.IOException;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
public class ConnectMain {
public static void main(String[] args) throws IOException {
unknownHostEx1();
unknownHostEx2();
connectionRefused();
}
private static void unknownHostEx1() throws IOException {
try {
Socket socket = new Socket("999.999.999.999", 80);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
private static void unknownHostEx2() throws IOException {
try {
Socket socket = new Socket("google.gogo", 80);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
private static void connectionRefused() throws IOException {
try {
Socket socket = new Socket("localhost", 45678);
} catch (ConnectException e) {
e.printStackTrace();
}
}
}
**실행 결과**
java.net.UnknownHostException: 999.999.999.999
java.net.UnknownHostException: google.gogo
java.net.ConnectException: Connection refused
UnknownHostException
호스트 자체를 알 수 없을 때 발생한다. TCP연결 시도 이전 단계에서 실패하는 경우이다
케이스 1 – 존재하지 않는 IP 대역
Socket socket = new Socket("999.999.999.999", 80);
999.999.999.999는 존재하지 않는 IP 대역이다. IP 형식은 맞지만 실제로 할당된 대역이 없기 때문에 연결 시도 자체가 불가능하다
케이스 2 – 존재하지 않는 도메인
Socket socket = new Socket("google.gogo", 80);
google.gogo라는 도메인은 DNS에 등록되어 있지 않다. 자바는 도메인을 IP로 변환하기 위해 DNS를 조회하는데, 조회 결과가 없으면 UnknownHostException을 던진다
두 케이스 모두 네트워크 패킷이 목적지에도 도달하기 전에 실패한다는 점이 공통점이다
ConnectException: Connection refused
Socket socket = new Socket("localhost", 45678);
이 예외는 앞의 UnknownHostException와는 성격이 다르다. “거절(refused)”이라는 단어에 주목할 필요가 있다. 거절은 상대방이 메시지를 받았다는 뜻이다
동작 원리
localhost(내 컴퓨터)는 커져 있으므로 TCP 연결 패킷이 목적지까지 도달한다- 서버 컴퓨터의 OS가 패킷을 수신하고 포트를 확인한다
- 45678 포트를 사용 중인 프로세스가 없으므로 OS가 연결을 거절한다
- OS는 클라이언트에게 TCP RST(Reset) 패킷을 전송한다
- 클라이언트는 RST 패킷을 수신하고
ConnectException: Connection refused를 던진다
TCP RST 패킷은 “이 연결은 비정상이므로 즉시 해제하라”는 신호다. RST를 받은 쪽은 추가 처리 없이 바로 연결을 해제해야 한다Connection refused가 발생하는 상황은 크게 두 가지다. 서버 IP는 유효하지만 해당 포트를 사용하는 프로세스가 없는 경우, 그리고 방화벽이 허용되지 않는 IP의 접근을 차단하는 경우다
두 예외의 핵심
| 구분 | UnknownHostException | ConnectException |
| 발생 지점 | DNS 조회 또는 IP 검증 단계 | TCP 연결 시도 단계 |
| 패킷 전송 여부 | 전송 안 됨 | 전송됨 |
| 원인 | 잘못된 IP 대역 또는 없는 도메인 | 포트 미사용, 방화벽 차단 |
| 서버 도달 여부 | 도달 안 됨 | 서버 OS까지 도달함 |
연결 예외를 만났을 때 방법은 명확하다. UnknownHostException 이면 호스트 주소 자체를 확인한다. IP 대역이 올바른지, 도메인이 실제로 존재하는지 점검한다. ConnectException: Connection refused이면 서버까지는 도달한 것이다. 서버 프로세스가 실행 중인지, 해당 포트로 리스닝 중인지, 방화벽 규칙이차단하고 있지는 않은지 확인한다