Java에서 네트워크 통신을 구현하는 방법은 크게 UDP(User Datagram Protocol)와 TCP(Transmission Control Protocol)로 나뉩니다. 이 글에서는 IP 주소, 포트 번호, 프로토콜의 기본 개념을 살펴보고, 실제 코드를 통해 데이터 송수신 과정을 단계별로 설명합니다.
네트워크 프로그래밍 기초
통신의 세 가지 요소
- IP 주소: 네트워크 상에서 각 기기를 식별하는 고유한 주소입니다.
- 포트(Port): 하나의 기기에서 실행 중인 여러 네트워크 애플리케이션을 구분하는 번호 (0~65535).
- 프로토콜: 데이터를 주고받는 규칙으로, 대표적으로 UDP와 TCP가 있습니다.
InetAddress 클래스 활용
InetAddress 클래스는 IP 주소를 표현하며, 호스트 이름이나 IP 문자열을 이용해 객체를 생성할 수 있습니다.
InetAddress address = InetAddress.getByName("192.168.0.1");
System.out.println(address.getHostAddress());
UDP 통신 구현
UDP는 연결 없이 데이터를 전송하며, 빠르지만 신뢰성이 낮습니다. Java에서는 DatagramSocket과 DatagramPacket을 사용합니다.
UDP 송신 예제
import java.net.*;
public class UDPSender {
public static void main(String[] args) throws Exception {
// 1. 소켓 생성
DatagramSocket socket = new DatagramSocket();
// 2. 데이터 패킷 준비
String message = "Hello, UDP!";
byte[] buffer = message.getBytes();
InetAddress targetIp = InetAddress.getByName("localhost");
int targetPort = 5000;
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, targetIp, targetPort);
// 3. 전송
socket.send(packet);
// 4. 리소스 정리
socket.close();
}
}
UDP 수신 예제
import java.net.*;
public class UDPReceiver {
public static void main(String[] args) throws Exception {
// 1. 특정 포트로 소켓 생성
int port = 5000;
DatagramSocket socket = new DatagramSocket(port);
// 2. 수신용 패킷 준비
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 3. 데이터 수신 (블로킹)
socket.receive(packet);
// 4. 내용 출력
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("수신 데이터: " + received);
socket.close();
}
}
TCP 통신 구현
TCP는 연결 지향 프로토콜로, 데이터 전송의 신뢰성과 순서를 보장합니다. Java에서는 Socket과 ServerSocket을 사용합니다.
TCP 클라이언트 예제
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String[] args) throws Exception {
// 1. 서버에 연결
String serverIp = "localhost";
int serverPort = 9000;
Socket socket = new Socket(serverIp, serverPort);
// 2. 출력 스트림으로 데이터 전송
OutputStream output = socket.getOutputStream();
String message = "Hello, TCP Server!";
output.write(message.getBytes());
// 3. 리소스 정리
socket.close();
}
}
TCP 서버 예제
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) throws Exception {
// 1. 서버 소켓 생성
int port = 9000;
ServerSocket serverSocket = new ServerSocket(port);
// 2. 클라이언트 연결 대기 (블로킹)
Socket clientSocket = serverSocket.accept();
// 3. 입력 스트림으로 데이터 읽기
InputStream input = clientSocket.getInputStream();
byte[] buffer = new byte[1024];
int length = input.read(buffer);
String received = new String(buffer, 0, length);
System.out.println("클라이언트로부터 수신: " + received);
// 4. 리소스 정리
clientSocket.close();
serverSocket.close();
}
}
실전 TCP 통신 예제
아래는 클라이언트가 메시지를 보내고 서버가 응답을 반환하는 간단한 대화형 예제입니다.
서버 코드
import java.io.*;
import java.net.*;
public class EchoServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8888);
System.out.println("서버 시작, 포트 8888에서 대기 중...");
Socket client = server.accept();
BufferedReader reader = new BufferedReader(
new InputStreamReader(client.getInputStream()));
PrintWriter writer = new PrintWriter(client.getOutputStream(), true);
String line = reader.readLine();
System.out.println("수신: " + line);
writer.println("서버 응답: " + line.toUpperCase());
client.close();
server.close();
}
}
클라이언트 코드
import java.io.*;
import java.net.*;
public class EchoClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8888);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
writer.println("안녕하세요, TCP!");
String response = reader.readLine();
System.out.println("서버 응답: " + response);
socket.close();
}
}