본문으로 건너뛰기

Ch 16.1 네트워킹 (Networking) 개요

네트워킹은 두 대 이상의 컴퓨터 혹은 디바이스들을 케이블이나 무선 통신망으로 연결하여 네트워크를 구성하고, 데이터를 주고받는 것을 의미합니다. 자바의 java.net 패키지를 사용하면 복잡한 네트워크 하드웨어 지식 없이도 손쉽게 네트워크 애플리케이션을 개발할 수 있습니다.

자바 네트워크 프로그래밍의 장점

자바는 OS에 독립적인 소켓 API를 제공하여, 동일한 코드가 Windows, Linux, macOS에서 동일하게 동작합니다.

1. IP 주소 (IP Address)

IP 주소는 네트워크 상에서 각각의 컴퓨터(호스트)를 식별하기 위해 부여되는 고유한 번호입니다.

항목IPv4IPv6
주소 형식192.168.0.12001:0db8:85a3::8a2e:0370:7334
크기32비트 (4바이트)128비트 (16바이트)
최대 주소 수약 43억 개사실상 무한
현황고갈 중전환 진행 중

특수 IP 주소

  • 127.0.0.1 (localhost): 자기 자신을 가리키는 루프백 주소
  • 0.0.0.0: 모든 네트워크 인터페이스를 의미 (서버 바인딩 시 사용)
  • 255.255.255.255: 브로드캐스트 주소

2. 포트 (Port) 번호

IP 주소가 건물의 주소라면, 포트(Port) 는 그 건물 안에 있는 특정한 '방 번호'와 같습니다. 하나의 IP 안에서 여러 서비스가 구분되는 방식입니다.

  • 범위: 0 ~ 65535
  • 0 ~ 1023: Well-known Ports (시스템 예약)
  • 1024 ~ 49151: Registered Ports (애플리케이션)
  • 49152 ~ 65535: Dynamic/Private Ports

잘 알려진 포트 (Well-known Ports)

포트프로토콜설명
20, 21FTP파일 전송
22SSH보안 원격 접속
23Telnet원격 접속 (비보안)
25SMTP이메일 발송
53DNS도메인 이름 해석
80HTTP웹 통신
443HTTPS보안 웹 통신
3306MySQL데이터베이스
5432PostgreSQL데이터베이스
6379Redis캐시
8080HTTP Alt개발용 웹 서버

3. TCP vs UDP 비교

항목TCPUDP
연결 방식연결 지향 (3-way handshake)비연결
데이터 전달 보장보장 (ACK 확인)보장 안 함
순서 보장보장보장 안 함
오류 감지/재전송있음없음
속도상대적으로 느림빠름
오버헤드작음
자바 클래스Socket, ServerSocketDatagramSocket, DatagramPacket
사용 사례HTTP/HTTPS, FTP, 이메일DNS, 스트리밍, 게임, VoIP

4. java.net 패키지 주요 클래스

java.net
├── InetAddress IP 주소 표현 및 DNS 조회
├── URL URL 파싱 및 표현
├── URLConnection URL 연결 추상 클래스
├── HttpURLConnection HTTP 연결 구현체
├── Socket TCP 클라이언트 소켓
├── ServerSocket TCP 서버 소켓
├── DatagramSocket UDP 소켓
├── DatagramPacket UDP 패킷 (데이터그램)
├── MulticastSocket UDP 멀티캐스트 소켓
└── URI URI 표현 (URL보다 엄격)

5. InetAddress: IP 주소 조회

import java.net.*;

public class InetAddressExample {
public static void main(String[] args) throws UnknownHostException {
// 1. 로컬 호스트 정보
InetAddress localhost = InetAddress.getLocalHost();
System.out.println("호스트 이름: " + localhost.getHostName());
System.out.println("로컬 IP: " + localhost.getHostAddress());

// 2. 도메인 이름으로 IP 조회 (DNS 조회)
InetAddress google = InetAddress.getByName("www.google.com");
System.out.println("구글 호스트: " + google.getHostName());
System.out.println("구글 IP: " + google.getHostAddress());

// 3. IP 주소로 직접 InetAddress 생성
InetAddress byIP = InetAddress.getByName("8.8.8.8"); // Google DNS
System.out.println("8.8.8.8 호스트: " + byIP.getHostName());

// 4. 도메인에 여러 IP가 있는 경우 (로드 밸런싱)
InetAddress[] naverIPs = InetAddress.getAllByName("www.naver.com");
System.out.println("\n네이버 IP 목록:");
for (InetAddress ip : naverIPs) {
System.out.println(" " + ip.getHostAddress());
}

// 5. 루프백 체크
System.out.println("\n루프백 여부: " + localhost.isLoopbackAddress());

// 6. 도달 가능 여부 확인 (ping과 유사)
try {
boolean reachable = google.isReachable(3000); // 3초 타임아웃
System.out.println("구글 접속 가능: " + reachable);
} catch (Exception e) {
System.out.println("접속 확인 실패: " + e.getMessage());
}
}
}

6. 클라이언트-서버 모델

대부분의 네트워크 애플리케이션은 클라이언트-서버(Client-Server) 모델을 따릅니다.

[클라이언트]                    [서버]
| |
|--- 연결 요청 (connect) -----> |
| |--- accept() 후 새 Socket 생성
|<-- 연결 수락 (accept) ------- |
| |
|--- 요청 전송 (request) -----> |
| |--- 처리
|<-- 응답 수신 (response) ----- |
| |
|--- 연결 종료 (close) -------> |
import java.net.*;

public class ClientServerConcept {
// 서버 역할: 특정 포트에서 클라이언트 연결 대기
static void serverRole() throws Exception {
// 1. 포트 8080에서 리스닝 시작
ServerSocket serverSocket = new ServerSocket(8080);

// 2. 클라이언트 연결 대기 (블로킹)
Socket clientSocket = serverSocket.accept(); // 연결 수락

System.out.println("클라이언트 연결: " + clientSocket.getInetAddress());

// 3. 통신 후 자원 해제
clientSocket.close();
serverSocket.close();
}

// 클라이언트 역할: 서버에 연결
static void clientRole() throws Exception {
// 서버 IP와 포트로 연결 요청
Socket socket = new Socket("127.0.0.1", 8080);

System.out.println("서버 연결 완료. 로컬 포트: " + socket.getLocalPort());
System.out.println("서버 주소: " + socket.getInetAddress() + ":" + socket.getPort());

socket.close();
}

public static void main(String[] args) {
System.out.println("클라이언트-서버 모델 개념 예제");
System.out.println("서버: ServerSocket.accept()로 연결 대기");
System.out.println("클라이언트: new Socket(host, port)로 연결 요청");
}
}

7. 소켓(Socket)이란?

소켓(Socket)은 네트워크 통신의 끝점(Endpoint) 입니다. 두 프로그램이 네트워크를 통해 통신하려면 각각 소켓을 만들고 연결해야 합니다.

소켓은 다음 4가지 정보로 식별됩니다:

  • 출발지 IP 주소
  • 출발지 포트 번호
  • 목적지 IP 주소
  • 목적지 포트 번호
[클라이언트 소켓]          [서버 소켓]
IP: 192.168.1.10 IP: 192.168.1.100
Port: 54321 <--> Port: 8080

8. HTTP 통신 기초

HTTP(HyperText Transfer Protocol)는 웹 브라우저와 웹 서버 간 통신 규약입니다.

HTTP 요청 메서드

메서드용도CRUD
GET데이터 조회Read
POST데이터 생성Create
PUT데이터 전체 수정Update
PATCH데이터 일부 수정Update
DELETE데이터 삭제Delete

HTTP 상태 코드

코드의미
200 OK요청 성공
201 Created리소스 생성 성공
400 Bad Request잘못된 요청
401 Unauthorized인증 필요
403 Forbidden권한 없음
404 Not Found리소스 없음
500 Internal Server Error서버 내부 오류

9. 실전 예제: InetAddress로 도메인 IP 조회 도구

import java.net.*;
import java.util.*;

public class DNSLookupTool {
/**
* 도메인의 모든 IP 주소와 상세 정보를 조회
*/
static void lookupDomain(String domain) {
System.out.println("\n=== " + domain + " 조회 ===");

try {
// DNS 조회
InetAddress[] addresses = InetAddress.getAllByName(domain);

System.out.println("IP 주소 수: " + addresses.length);
for (InetAddress addr : addresses) {
String type = addr instanceof Inet6Address ? "IPv6" : "IPv4";
System.out.printf(" [%s] %s%n", type, addr.getHostAddress());

// 루프백, 사이트 로컬, 링크 로컬 여부
System.out.printf(" 루프백: %b, 사이트로컬: %b%n",
addr.isLoopbackAddress(), addr.isSiteLocalAddress());
}

} catch (UnknownHostException e) {
System.out.println("알 수 없는 호스트: " + domain);
}
}

static void showLocalNetworkInfo() throws Exception {
System.out.println("=== 로컬 네트워크 정보 ===");
InetAddress local = InetAddress.getLocalHost();
System.out.println("컴퓨터 이름: " + local.getHostName());
System.out.println("로컬 IP: " + local.getHostAddress());
System.out.println("IPv6 여부: " + (local instanceof Inet6Address));

// 네트워크 인터페이스 목록
System.out.println("\n네트워크 인터페이스 목록:");
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
while (nets.hasMoreElements()) {
NetworkInterface nic = nets.nextElement();
if (nic.isUp() && !nic.isLoopback()) {
System.out.println(" " + nic.getDisplayName());
Enumeration<InetAddress> addrs = nic.getInetAddresses();
while (addrs.hasMoreElements()) {
System.out.println(" IP: " + addrs.nextElement().getHostAddress());
}
}
}
}

public static void main(String[] args) throws Exception {
showLocalNetworkInfo();

// 잘 알려진 도메인 조회
lookupDomain("localhost");
lookupDomain("www.google.com");
lookupDomain("invalid.domain.xyz"); // 없는 도메인
}
}
고수 팁: 소켓 통신 레이어

자바 소켓은 OS의 TCP/IP 스택을 래핑한 것입니다. 내부적으로는 OS가 실제 패킷 조립/분해, 오류 감지, 재전송을 담당합니다. 자바 코드는 스트림(InputStream/OutputStream)으로 추상화된 인터페이스를 통해 데이터를 주고받습니다.